web-dev-qa-db-fra.com

Couche DataAccess pour renvoyer des objets de domaine en cas de Ado.net?

Je crée un projet dans lequel je vais utiliser ADO.NET en tant que couche d'accès aux données pour interagir avec la base de données.

Maintenant, la chose où je suis assez confus est avec:

1) Dois-je avoir des objets de domaine dans cette application?

2) Le résultat de ma requête SQL doit-il toujours être lié à objets de domaine ?

3) Si je n'utilise pas d'objets de domaine, dois-je toujours renvoyer des modèles personnalisés de la couche d'accès aux données contenant tout ce que je souhaite renvoyer dans mon service API Web?

4) Si j'utilise domain models et s'il existe un scénario dans lequel je souhaite afficher des données provenant de plusieurs tables ou un scénario comme celui-ci, par exemple:

public class Employee
   {
      int id;
      List<Skills>();
   }

Je peux facilement le faire dans EF, mais avec ado.net et avec un objet de domaine qui aurait la structure suivante:

public class Employee
   {
       int id;
   }

   public class Skill
   {
       int id;
       int EmployeeId;
   }

Ofcouse, je peux d’abord obtenir la liste des employés, puis pour chaque employé, je peux obtenir une liste de compétences basée sur l’identité de l’employé, mais ce ne sera pas douloureux. simple en EF basé sur la propriété de navigation et en évitant les frais généraux comme ci-dessous: 

var employees = //get listof employee in this case domain model 
                  List<Employee>
var employeeModel = new List<EmployeeModel>();
foreach(var employee in employees)
{
   EmployeeModel model = new EmployeeModel();
   model.id = employee.id;
   var skills = GetSkill(employee.id);//Get list of skills in this case 
                domain model List<Skill>;
   employeeModel.Skills =  new List<SkillModel>();
   foreach(var skill in skills)
   {
      SkillModel sm = new SkillModel();
      sm.Id = skill.Id;
      employeeModel.Skills.Add(smm);
   }
   employeeModel.Add(model);
}

Enfin, ce EmployeeModel sera renvoyé en réponse dans mon service Api Web. Par conséquent, ce EmployeeModel ne contiendra que les propriétés que je renverrai dans mon noeud final WebApi.

Quelle devrait être l’architecture envisagée lorsqu’on travaillera avec ado.net en tant que couche d’accès aux données et j’apprécierai vraiment que quelqu'un puisse m'aider, s'il vous plaît, à répondre à la question susmentionnée.

Remarque: Je ne souhaite pas utiliser ORM (Entity Framework ou Dapper, etc.).

8
ILoveStackoverflow

1) Dois-je avoir des objets de domaine dans cette application?

vous seul pouvez répondre à cela; La bonne réponse dépend fortement de ce que vous faites avec les résultats d'une requête de base de données. Si vous avez une logique spécifique aux champs dans votre code C #, il est judicieux d'utiliser des DTO (classes d'entités POCO). Mais parfois, vous voudrez peut-être simplement exécuter une requête et renvoyer les résultats sous forme de code JSON. Dans ce cas, les DTO peuvent être excessifs.

2) Le résultat de ma requête SQL doit-il toujours être lié à des objets de domaine?

non, c'est à vous de décider. Vous pouvez utiliser DbDataReader directement pour gérer les résultats de la requête ou les charger dans DataTable (ou une structure plus légère similaire pouvant être proposée par votre bibliothèque d'accès aux données).

3) Si je n'utilise pas d'objets de domaine, dois-je toujours renvoyer des modèles personnalisés de la couche d'accès aux données contenant tout ce que je souhaite renvoyer dans mon service API Web?

Si vous n'utilisez pas de modèles POCO, vous pouvez composer du JSON dans votre code et le renvoyer sous forme de ActionResult.

4) Si j'utilise des modèles de domaine et s'il existe un scénario dans lequel je souhaite afficher les données de plusieurs tables

Si vous n'utilisez pas ORM comme EF 2 cas possibles ici:

  • si cela résulte de 2 (ou plusieurs) tables jointes: pour cela, vous pouvez ajouter un modèle POCO spécial exactement pour ce résultat de requête ou utiliser un conteneur de données générique tel que DataTable pour gérer le résultat.
  • s'il s'agit d'un parent-enfant (1-n): exécutez 2 requêtes et obtenez le résultat sous forme de 2 collections de modèles POCO (par exemple, List<Employee> et List<Skills> de ces employés). Ensuite, si vous devez accéder aux enfants de l'entité 'mère' concrète, effectuez un filtrage supplémentaire avec LINQ.

Si vous ne souhaitez pas utiliser EF ou Dapper, vous pouvez également vérifier ma bibliothèque qui peut être utilisé avec des modèles POCO ou avec des structures génériques telles que DataTable (en plus de cela, il offre une structure RecordSet).

5
Vitaliy Fedorchenko

Créer un modèle de domaine en application est une bonne approche. Il vous suffit de lier les données aux modèles. Créer des modèles selon la table de base de données. Si une table fait référence à une autre, incluez-la également dans le modèle, cela vous facilitera la tâche de mapper les données à modéliser. Je vous recommanderais d'utiliser micro ORM, cela vous aiderait à mapper les données sur les modèles, sinon vous auriez besoin de vous mapper vous-même.

2
Usama Kiyani

Entity Framework et le chargement paresseux des objets référencés est une approche raisonnable. Pour étendre votre modèle, prenez en compte les éléments suivants.

Créez une vue SQL Server qui relie la table Employé et compétences et ajoutez-la au modèle EF. La vue peut être aussi minimale ou maximale que vous le souhaitez (par exemple, minimale uniquement dans l'ID d'objet ou maximale dans tous les champs).

Dans cette vue, sélectionnez tous les enregistrements avec un ID de compétence particulier et vous avez maintenant les employés dont vous avez besoin. Comme la vue est compilée dans SQL Server, elle sera aussi rapide que possible.

Vous pouvez également joindre les objets Employé et Compétence dans votre code et renvoyer uniquement les employés. Dans LINQ, vous pouvez afficher le code SQL généré pour votre code.

2
pixelda

Je vais essayer de donner des réponses plus spécifiques qui devraient vous donner des directives pratiques.

1) Dois-je avoir des objets de domaine dans cette application?

Ça dépend. Pour des applications très simples, vous n'en avez pas besoin. Pour des applications plus complexes, c'est absolument recommandé.

2) Le résultat de ma requête SQL doit-il toujours être lié à des objets de domaine?

Oui si vous allez avoir le modèle de domaine. Non si vous n'avez pas de modèle de domaine ou si vous essayez de renvoyer une valeur simple (par exemple, un entier).

3) Si je n'utilise pas d'objets de domaine, dois-je toujours renvoyer des modèles personnalisés de la couche d'accès aux données contenant tout ce que je souhaite renvoyer dans mon service API Web?

Si vous n'avez pas le modèle de domaine, votre DAL devient le serveur direct du service API Web. Donc, quels que soient les besoins de l’API Web, ils doivent provenir de DAL. Vous pouvez renvoyer tout cela en une fois (un appel de méthode) ou vous pouvez faire appel à api DAL via plusieurs appels de méthode. Évidemment, il est préférable de tout récupérer en une fois, mais cela s’intègre mieux dans la couche service. DAL devrait retourner l'agrégat à la fois. Mais sans modèle de domaine et sans approches plus avancées, cela peut être trop compliqué.

4) Si j'utilise des modèles de domaine et s'il existe un scénario dans lequel je souhaite afficher des données provenant de plusieurs tables ou d'un scénario comme celui-ci

Je voudrais lancer une requête SQL avec rejoindre. Ensuite, je parcourais les lignes et créais les objets parent et enfant à partir des lignes, puis je retournais l'objet de cette manière. En fait, c’est ce que fait Entity Framework avec les propriétés de navigation: il charge avec enthousiasme l’ensemble de la structure à l’aide de la jointure. Il n'exécute pas plusieurs requêtes, et vous ne devriez pas non plus, si vous souhaitez l'optimiser au maximum.

Faites-moi savoir si vous avez des questions sur quelque chose que j'ai mentionné.

2
Tengiz

Je suis d'accord avec Tengiz answer. Cependant, vous pouvez utiliser Modèle d’enregistrement actif et si par objet de domaine vous voulez utiliser une approche de conception pilotée par domaine, votre DAL doit résumer la logique d’accès aux données et il vaut mieux utiliser Modèle de référentiel pour chaque objet d'agrégat de domaine. En outre, vous pouvez séparer vos modèles pour lire et écrire, puis vous pouvez utiliser CQRS pattern.

Dans tous les cas, vous devez exécuter vos commandes SQL/procédures stockées dans vos objets d'accès aux données, puis renseigner vos objets de domaine à partir du datareader ADO.NET, des jeux de données et des données, et les exposer à votre modèle de domaine.

En remarque, DTO, comme son nom l'indique, est utilisé pour communiquer avec votre domaine interne et il est recommandé de séparer les objets de domaine des DTO (contrats de données).

1
HojjatK

Je voulais juste vous proposer une autre alternative pour le scénario 4.

4) Si j'utilise des modèles de domaine et s'il existe un scénario dans lequel je souhaite afficher des données provenant de> plusieurs tables ou d'un scénario comme celui-ci

Examinez la réponse fournie à la question suivante: Chargement d’objets apparentés en mémoire (sans ORM)

J'utilise des types anonymes et LINQ pour mapper les données d'une requête sur plusieurs tables. 

0
Tim Robinson