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

发布于 2024-10-01 01:44:16 字数 688 浏览 1 评论 0原文

一个基于经典三层的项目:UI(在这个问题中并不重要)、业务逻辑层和数据访问层。我有几个表:客户 产品 订单 用户。设计应该是:

//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 方法的组合操作(过滤/连接/选择)之外什么也没有。很奇怪吗?正确的方法是什么?

A project base on classic 3 layers: UI(not important in this question), business logic layer and data access layer. I have several tables: Customers Products Orders Users. The design is supposed to be:

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

What confuses me is that I find that all methods in DAL are GetAllXXXX. And I have to admit that this design is working fine. In DAL there is nothing but GetAll methods. In BLL there is nothing but combined operations(filter/join/select) to GetAll methods. Is it weird? What's the correct way?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

拥抱我好吗 2024-10-08 01:44:17

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

对我来说唯一的区别是:

  • 我使用 IQueryable 而不是 IEnumerable (为了获得延迟执行)
  • 我有一个通用存储库(Repository) ):
    • IQueryable;查找()
    • 无效添加(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 的持久性,不关心实际类型或任何业务逻辑。

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

No, that's not weird, and in fact that is very similar to how i do it.

Only differences for me:

  • I use IQueryable<T> instead of IEnumerable<T> (to get deferred exec)
  • I have a generic repository (Repository<T>):
    • IQueryable<T> Find()
    • void Add(T)
    • etc etc

This way, my repositories stay clean/simple.

So your BLL could be implemented like this:

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!
}

Makes the BLL do the projection/work/logic. Repositories just handle persistence of T, doesn't care about the actual type, or any business logic.

That's how i do it anyway.

巡山小妖精 2024-10-08 01:44:17

考虑一下您的数据访问层可能提供如下服务:

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

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

在 BL 中进行过滤/加入/选择,我更喜欢 IQueryable 而不是 IEnumerable。这意味着在调用 Single()First()ToList() 之前,BL 代码中的给定语句不会执行。 BL 代码中的 code>、Count() 等。

Consider that your data access layer could be providing services like:

  • Create
  • Update
  • Delete
  • GetSingleCustomer()
  • CalculateUpperManagementTuesdayReport()

I wouldn't say it's terribly odd, but perhaps your DAL doesn't need to provide those services, as your application doesn't require them.

Having your filter/join/select in the BL, I'd prefer IQueryable<t> instead of IEnumerable<T>. This means that the execution of a given statement in the BL code doesn't happen until you call Single(), First(), ToList(), Count(), etc, etc within the BL code.

从来不烧饼 2024-10-08 01:44:17

我的问题是,如果合并当前的 BLL 和 DAL,您会损失什么? - 他们似乎都在处理弥合从持久数据(DB)到对象的差距。似乎是最简单的事情。
另一种看待它的方式是改变本地化?例如,如果 DAL 层发生变化,它会被隔离还是会波及到上层(这是不希望的)。

理想情况下,BLL 应该封装您所在领域的规则/工作流程,即领域知识。例如,如果某些客户受到区别对待。 DAL 的存在是为了将数据从持久状态转换为对象(或由更高层使用的数据结构),反之亦然。这是我今天的理解...

My question would be what would you lose if you merge the current BLL and the DAL? - they both seem to be dealing with bridging the gap from persisted data (DBs) to objects.. Seems like the simplest thing that would work.
Another way of looking at it would be is change localized ? e.g. if there is a change in DAL layer, would that be isolated or would it ripple through into the upper layers (which is undesirable).

The BLL ideally should encapsulate the rules/workflows of your domain aka domain knowledge. e.g. if certain customers are treated differently. The DAL exists to transform your data from the persisted state into objects (or data structs to be consumed by higher layers) and vice versa. That's my understanding as of today...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文