数据访问层(DAL)中的LINQ查询方法

时间:2010-11-03 04:02:40

标签: c# .net linq architecture data-access-layer

基于经典3层的项目:UI(在此问题中不重要),业务逻辑层和数据访问层。我有几个表:Customers Products Orders Users。设计应该是:

//DAL methods
public IEnumerable<Customer> GetAllCustomers()
public IEnumerable<Product> GetAllProducts()
public IEnumerable<Order> GetAllOrders()
public IEnumerable<User> GetAllUsers()
//BLL methods
public IEnumerable<Order> GetOrders(long CustomerID)
public IEnumerable<Product> GetProducts(long CustomerID)
public IEnumerable<Product> GetProducts(long OrderID)

令我困惑的是,我发现DAL中的所有方法都是GetAllXXXX。我不得不承认这个设计工作正常。在DAL中,只有GetAll方法。在BLL中,只有组合操作(过滤/加入/选择)到GetAll方法。这很奇怪吗?什么是正确的方法?

3 个答案:

答案 0 :(得分:2)

不,这并不奇怪,事实上这与我的表现非常相似。

只有我的差异:

  • 我使用IQueryable<T>代替IEnumerable<T>(以获得延迟执行)
  • 我有一个通用存储库(Repository<T>):
    • IQueryable<T> Find()
    • void Add(T)
    • 等等

这样,我的存储库保持干净/简单。

所以你的BLL可以像这样实现:

public IEnumerable<Order> GetOrders(long CustomerID)
{
   Repository<Order> orderRepository = new Repository<Order>(); // should use DI here, but i digress
   return orderRepository
             .Find() // no query executed...
             .Where(o => o.CustomerID == CustomerID) // still nothing...
             .ToList(); // query executed, with BL applied! cool!
}

使BLL执行投影/工作/逻辑。存储库只处理T的持久性,不关心实际类型或任何业务逻辑。

无论如何,我就是这样做的。

答案 1 :(得分:1)

请考虑您的数据访问层可以提供以下服务:

  • 创建
  • 更新
  • 删除
  • GetSingleCustomer()
  • CalculateUpperManagementTuesdayReport()

我不会说它非常奇怪,但也许您的DAL不需要提供这些服务,因为您的应用程序不需要它们。

在BL中使用过滤器/加入/选择,我更喜欢IQueryable<t>而不是IEnumerable<T>。这意味着,在BL中调用Single()First()ToList()Count()等之后,BL代码中的给定语句的执行才会发生。代码。

答案 2 :(得分:0)

我的问题是,如果合并当前的BLL和DAL,你会失去什么? - 它们似乎都在处理从持久数据(DB)到对象之间的差距。看起来像最简单的事情。 看待它的另一种方式是改变本地化?例如如果DAL层发生了变化,那么它是否会被隔离或是否会进入上层(这是不可取的)。

理想情况下,BLL应该封装域名规则/工作流程,即域知识。例如如果对某些客户的处理方式不同DAL用于将数据从持久状态转换为对象(或更高层消耗的数据结构),反之亦然。那是我今天的理解......