数据访问层(DAL)中的LINQ查询方法
一个基于经典三层的项目: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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
不,这并不奇怪,事实上这与我的做法非常相似。
对我来说唯一的区别是:
IQueryable
而不是IEnumerable
(为了获得延迟执行)Repository) ):- 等等等等
IQueryable;查找()
无效添加(T)
这样,我的存储库保持干净/简单。
因此,您的 BLL 可以这样实现:
使 BLL 执行投影/工作/逻辑。存储库只处理 T 的持久性,不关心实际类型或任何业务逻辑。
无论如何,我就是这样做的。
No, that's not weird, and in fact that is very similar to how i do it.
Only differences for me:
IQueryable<T>
instead ofIEnumerable<T>
(to get deferred exec)Repository<T>
):IQueryable<T> Find()
void Add(T)
This way, my repositories stay clean/simple.
So your BLL could be implemented like this:
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.
考虑一下您的数据访问层可能提供如下服务:
GetSingleCustomer()
CalculateUpperManagementTuesdayReport()
我不会说这非常奇怪,但也许您的 DAL 不需要提供这些服务,因为您的应用程序不需要它们。
在 BL 中进行过滤/加入/选择,我更喜欢
IQueryable
而不是IEnumerable
。这意味着在调用Single()
、First()
、ToList()
之前,BL 代码中的给定语句不会执行。 BL 代码中的 code>、Count()
等。Consider that your data access layer could be providing services like:
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 ofIEnumerable<T>
. This means that the execution of a given statement in the BL code doesn't happen until you callSingle()
,First()
,ToList()
,Count()
, etc, etc within the BL code.我的问题是,如果合并当前的 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...