分离 Linq To SQL 和 DTO 的关注点
-
09-06-2019 - |
题
我最近启动了一个新的 Webforms 项目,并决定将业务类与任何 DBML 引用分开。相反,我的业务层类访问离散的数据层方法,并返回 DTO 的集合。因此数据层可能会像下面这样投影 DTO:
(from c in dataContext.Customers
where c.Active == true
select new DTO.Customer
{
CustomerID = c.CustomerID,
Name = c.CustomerName,
...
}).ToList()
尽管构建 DTO 对象会增加工作量,但这感觉像是业务层和数据层之间紧密绑定的更好方法,并且意味着我可以在不存在数据库的情况下测试业务层。
我的问题是,这是一个好的做法吗?是否有一种生成 DTO 的方法(可能通过 SQLMetal),以及随着项目的进展我可能会遇到哪些其他问题。
解决方案
我不知道这是否是最佳实践,但我在不久前编写过类似的代码,因为我也觉得可以通过使用我自己的类而不是应用程序中的 LINQ 设计器生成的类来改进关注点分离。
您可能需要考虑仅从数据访问方法返回 IQueryable<Customer> 而不是 IList<Customer>。由于 IQueryable<T> 继承自 IEnumerable<T>,应用程序的其余部分应该能够很好地处理它。您还可以在确实需要时将其转换为列表。
这样做的优点是您可以非常轻松地动态修改查询并最大限度地减少从 SQL Server 返回的数据量。
例如。如果您的方法签名是可笑的u003CCustomer>getCustomers()您可以通过调用getCustomers()。其中(c => c.customerid == 101).single();
在此示例中,只会从数据库返回一条记录,而我想当前您的代码将返回所有客户,或者您需要编写单独的方法(因此非常重复的代码)来满足您可能想要的所有不同的事情来过滤。
其他提示
我认为在大多数情况下处理 LINQ 时不需要 DTO 对象。生成的 LINQ 类可以轻松测试。LINQ 使您能够使用相同的查询从不同的源查询数据。它使您能够针对对象列表而不是真实的数据库来测试查询。