猿问

在 Ado.net 的情况下,DataAccess 层返回域对象?

我正在创建一个项目,在该项目中我将使用 ADO.NET 作为数据访问层与数据库进行交互。


现在我很困惑的是:


1)我应该在这个应用程序中有域对象吗?


2) 我的 sql 查询结果是否应该始终与域对象绑定?


3)如果我不使用域对象,那么我是否应该始终从数据访问层返回自定义模型,其中包含我想要在我的 web api 服务中返回的所有内容?


4)如果我使用域模型并且如果有一个场景我想显示来自多个表的数据或像这样的场景,例如:


public class Employee

   {

      int id;

      List<Skills>();

   }

我可以在 EF 中轻松做到这一点,但使用 ado.net 和域对象,其结构如下所示,我将如何实现这一点:


public class Employee

   {

       int id;

   }


   public class Skill

   {

       int id;

       int EmployeeId;

   }

Ofcouse 我可以首先获取员工列表,然后对于每个员工,我可以根据员工 ID 获取技能列表,但这不是很痛苦,我必须为每个员工触发查询以获得其相应的技能,这在 EF 中非常简单基于导航属性并避免像下面这样的开销:


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);

}

最后,这个 EmployeeModel 将在我的 Web Api 服务中作为响应返回,因此这个 EmployeeModel 将只保存我将在我的 WebApi 端点中返回的那些属性。


在使用 ado.net 作为数据访问层时应该考虑什么架构,如果有人可以帮助我解决上述 4 个问题,我将不胜感激。


注意:我不想使用 ORM(实体框架或 Dapper 等)。


拉莫斯之舞
浏览 88回答 3
3回答

慕容708150

实体框架和引用对象的延迟加载是一种合理的方法。要扩展您的模型,请考虑以下事项。创建一个链接 Employee 和 Skills 表的 SQL Server 视图,并将其添加到 EF 模型中。视图可以是您想要的最小或最大(例如,在对象 ID 中最小或在所有字段中最大)。从此视图中,选择具有特定技能 ID 的所有记录,您现在拥有所需的员工。由于视图是在 SQL Server 中编译的,因此它会尽可能快地完成。您还可以在代码中加入 Employee 和 Skill 对象并仅返回员工。在 LINQ 中,您可以查看为您的代码生成的 SQL

炎炎设计

我将尝试给出更具体的答案,这些答案应该会给您提供实用的指导。1)我应该在这个应用程序中有域对象吗?这取决于。对于非常简单的应用程序,您不需要它。对于更复杂的应用程序,绝对推荐。2) 我的 sql 查询结果是否应该始终与域对象绑定?是的,如果您要拥有域模型。如果您没有域模型或者您试图返回一个简单的值(例如整数),则否。3)如果我不使用域对象,那么我是否应该始终从数据访问层返回自定义模型,其中包含我想要在我的 web api 服务中返回的所有内容?如果您没有域模型,那么您的 DAL 将成为 Web api 服务的直接仆人。因此,无论 web api 需要什么,它都需要从 DAL 中获取。您可以一次性返回所有内容(一个方法调用),或者您可以通过多个方法调用让 api 调用 DAL。显然,一次性检索所有内容更好,但这更适合服务层。DAL 应该一次返回聚合。但是如果没有领域模型和更高级的方法,这可能是太多的考虑。4)如果我使用域模型并且如果有一个场景我想显示来自多个表的数据或这样的场景我会运行一个带有连接的 SQL 查询。然后我会遍历行并从行创建父对象和子对象,然后我会以这种方式返回对象。事实上,这就是 Entity Framework 对导航属性所做的事情——它使用 join 急切地加载整个结构。它不会执行多个查询,如果您想将其优化到最大值,您也不应该执行。如果您对我提到的任何事情有任何疑问,请告诉我。

开心每一天1111

1)我应该在这个应用程序中有域对象吗?只有你能回答这个问题;正确答案很大程度上取决于您对数据库查询结果的处理方式。如果您的 C# 代码中有一些特定于字段的逻辑,则使用 DTO(POCO 实体类)是有意义的。但有时您可能只想执行一些查询并以 JSON 形式返回结果,在这种情况下,DTO 可能会过大。2) 我的 sql 查询结果是否应该始终与域对象绑定?不,这取决于你。您可以DbDataReader直接使用来处理查询结果,或将它们加载到DataTable(或您的数据访问库可以提供的类似的更轻量级的结构)中。3)如果我不使用域对象,那么我是否应该始终从数据访问层返回自定义模型,其中包含我想要在我的 web api 服务中返回的所有内容?如果您不使用 POCO 模型,您可以在代码中编写 JSON 并将其作为 ActionResult 返回。4)如果我使用域模型并且如果有我想显示来自多个表的数据的场景如果您不使用像 EF 2 这样的 ORM 可能的情况:如果这是 2 个(或更多)连接表的结果:为此,您可以为此查询结果添加特殊的 POCO 模型,或者使用像 DataTable 这样的通用数据容器来处理结果如果这是父子 (1-n):执行 2 个查询并以 2 个 POCO 模型集合(例如,这些员工的集合)的形式获取List<Employee>结果List<Skills>。然后,如果您需要访问具体的“父”实体的子实体,请使用 LINQ 执行额外的过滤。如果您不想使用 EF 或 Dapper,您还可以查看我的库,该库可用于 POCO 模型或 DataTable 等通用结构(此外它还提供 RecordSet 结构)。
随时随地看视频慕课网APP
我要回答