2010-11-03 68 views
2

基於經典3層的項目:UI(在此問題中不重要),業務邏輯層和數據訪問層。我有幾個表格:CustomersProductsOrdersUsers。設計應該是:數據訪問層(DAL)中的LINQ查詢方法

//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方法的組合操作(filter/join/select)以外,沒有其他任何操作。這是不是很奇怪?什麼是正確的方法?

回答

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

考慮你的數據訪問層可能是提供類似的服務:

  • 創建
  • 更新
  • 刪除
  • GetSingleCustomer()
  • CalculateUpperManagementTuesdayReport()

我不會說這很奇怪,但也許您的DAL不需要提供這些服務,因爲您的應用程序不需要它們。

有你的過濾器/加入/在BL中選擇,我寧願IQueryable<t>而不是IEnumerable<T>。這意味着只有在BL代碼中調用Single(),First(),ToList(),Count()等,才能執行BL代碼中給定語句的執行。

0

我的問題是,如果你合併當前的BLL和DAL,你會失去什麼? - 他們似乎都在處理從持久數據(DB)到對象的差距。看起來像最簡單的事情會起作用。 查看它的另一種方法是更改​​本地化?例如如果DAL層發生變化,是否會被隔離或是否會波及到上層(這是不可取的)。

理想情況下,BLL應該封裝您的域的規則/工作流程,即域知識。例如如果某些客戶被區別對待。 DAL存在將您的數據從持久狀態轉換爲對象(或數據結構被更高層使用),反之亦然。這是我對今天的理解...