![](/img/trans.png)
[英]Where should Model reside in case of 3-tier Domain Driven designed application?
[英]Where do objects merge/join data in a 3-tier model?
它可能是一個簡單的3層問題。 我只是想確保我們為此使用最佳實踐,而我對結構並不那么熟悉。
我們分為三層:
讓我們考慮一下我們有[Persons]數據庫的地方的設置。 他們都可以有多個[Address],並且我們具有所有[PostalCode]和相應城市名稱的完整列表。
要做的是,我們從其他表中加入了許多細節。
{關系} / [表]
現在,我們要為人構建DAL。 PersonBO的外觀如何以及何時發生連接? 獲取所有城市名稱和可能的地址是業務層問題嗎? 人? 還是DAL應該在將PersonBO返回BAL之前完成所有這些工作?
Class PersonBO
{
public int ID {get;set;}
public string Name {get;set;}
public List<AddressBO> {get;set;} // Question #1
}
//問題1:我們是否在返回PersonBO之前檢索對象,並且應該將其改為Array? 還是對n層/ 3層完全錯誤?
Class AddressBO
{
public int ID {get;set;}
public string StreetName {get;set;}
public int PostalCode {get;set;} // Question #2
}
//問題2:我們進行查找還是將郵政編碼留待以后查找?
誰能解釋以什么順序拉扯哪些物體? 建設性的批評是非常受歡迎的。 :O)
您是在重新發明輪子; ORM已經為您解決了大多數此類問題,您將發現自己做起來有些棘手。
諸如Linq to SQL,Entity Framework和NHibernate之類的ORM做到這一點的方法是一種稱為關聯的延遲加載的技術(可以選擇通過快速加載來替代)。
當您拉起Person
,它不會加載Address
除非您明確要求,否則將再次進行數據庫往返(延遲加載)。 您還可以基於每個查詢指定要為每個人加載Address
(急切加載)。
在某種意義上,從這個問題開始,您基本上是在問是否應該為PersonBO
執行懶惰的或急切的AddressBO
加載,答案是:都不是。 沒有一種方法可以普遍起作用。 默認情況下,您可能應該延遲加載,這樣您就不會進行很多不必要的連接。 為了實現這一點,您必須使用延遲加載機制來構建PersonBO
,該機制保留對DAL的一些引用。 但是,您仍然希望可以選擇“預先加載”,這需要內置到“業務訪問”邏輯中。
如果需要返回具有從許多不同表填充的特定屬性的高度定制的數據集,另一種選擇是根本不返回PersonBO
,而使用數據傳輸對象 (DTO)。 如果您實現默認的延遲加載機制,則有時可以將其替換為快速加載版本。
僅供參考,數據訪問框架中的惰性加載程序通常是使用關聯本身中的加載邏輯構建的:
public class PersonBO
{
public int ID { get; set; }
public string Name { get; set; }
public IList<AddressBO> Addresses { get; set; }
}
這只是一個POCO,魔術發生在實際的列表實現中:
// NOT A PRODUCTION-READY IMPLEMENTATION - DO NOT USE
internal class LazyLoadList<T> : IList<T>
{
private IQueryable<T> query;
private List<T> items;
public LazyLoadList(IQueryable<T> query)
{
if (query == null)
throw new ArgumentNullException("query");
this.query = query;
}
private void Materialize()
{
if (items == null)
items = query.ToList();
}
public void Add(T item)
{
Materialize();
items.Add(item);
}
// Etc.
}
(這顯然不是生產級的,只是為了演示該技術;您從查詢開始,直到需要時才實現實際列表。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.