根據我的經驗構建Web應用程序,我一直使用n層方法。從數據庫獲取數據並填充對象的DAL,以及從DAL獲取對象並執行其所需的任何業務邏輯的BLL,以及從BLL顯示數據的網站。 我最近開始學習LINQ,並且大多數示例都顯示了從Web應用程序代碼隱藏中發生的查詢(可能我只看到了過分簡化的示例)。在n層架構中,這一直被認爲是一個很大的禁忌。
我有點不確定如何構建一個新的Web應用程序。我一直在使用VS2008中的服務器資源管理器和dbml設計器來創建dbml和對象關係。這似乎有點我不清楚,如果DBML將被認爲是DAL層,如果網站要調用一個BLL,然後會做LINQ查詢等中的方法
什麼是一些通用架構的最佳實踐,或者接近使用LINQ to SQL創建Web應用程序解決方案?LINQ to SQL Web應用程序最佳實踐
回答
恐怕你確實看到過分簡化的例子。 LINQ to SQL(System.Data.Linq)是您的DAL層。 L2S生成的類是您的域(但不要與Domain-Driven Design混淆)。最重要的是,您仍然可以編寫業務層。
我總是儘量防止泄漏的LINQ to SQL DataContext
到演示層(你的web應用程序)。所以它不應該能夠創建或提交DataContext
。您也不應將IQueryable<T>
對象返回到表示層。 IMO業務層應該完全控制DataContext
(工作單元)的生命週期以及SQL查詢的形狀。
但是,有幾種口味。有些人試圖放鬆這些限制。其他人甚至更進一步。這取決於你自己的口味和應用程序的大小。應用程序越大,添加抽象層的理由就越多。
當不允許IQueryable
S和其他數據離開業務層相關的東西,你最終會遇到一些有趣的挑戰。例如,表示層必須指示業務層如何對結果進行排序。雖然您可以讓表示層自行對結果進行排序,但這意味着您必須從表示層獲取數據庫和頁面的所有數據,這會導致系統性能很差。這個問題有幾種解決方案。在所有情況下,您都需要通知業務層如何爲您分類結果。當您搜索LINQ dynamic sort時,可在此處找到解決方案。我自己寫了這樣一個解決方案,here。
,從離開你的BL會帶來不允許IQueryable
是另一個挑戰是,也域對象往往不能離開你的BL。大多數LINQ to SQL域對象將包含延遲加載的屬性(例如,對其他域對象的集合)。但是,如果DataContext
處於業務層的控制之下,那麼它將在您將結果返回到表示層之前進行處置。當演示文稿比訪問延遲加載的屬性時,將發生異常,因爲DataContext
已被處置。當您在業務層中處理DataContext
時,此行爲當然是「按設計」。允許表示層獲得延遲加載屬性意味着BL失去對發送到數據庫的查詢的控制權,從而失去對性能的控制。
要解決此問題,您應該將BL中的數據傳輸對象(DTO)返回到表示層。 DTO將只包含數據和否內部DataContext
,並且沒有延遲加載的屬性。 DTO可以根據實際需求進行特殊格式化。 DTO當然會導致編碼開銷,因此係統的大小和性能需求必須證明它是正確的。爲了讓自己更容易,我傾向於將靜態投影方法放在DTO上。雖然這不符合separation of concerns原則,但我認爲它是一個非常實用的解決方案。看看例如在此CustomerDTO:
public class CustomerDTO
{
public int CustomerId { get; set; }
public string Name { get; set; }
// City is flatterned from Address.City.
public string City { get; set; }
internal static IQueryable<CustomerDTO> AsDTO(IQueryable<Customer> customers)
{
return
from customer in customers
select new CustomerDTO()
{
CustomerId = customer.Id,
Name = customer.Name,
City = customer.Address.City
};
}
}
這DTO限定了內部AsDTO
方法,這是能夠Customer
域對象的集合轉換成的CustomerDTO
DTO的集合。這使得將域對象轉換爲DTO更容易。看看例如在此BL方法:
public static CustomerDTO[] GetCustomersByCountry(string country)
{
using (var db = ContextFactory.CreateContext())
{
IQueryable<Customer> customers =
(from customer in db.Customers
where customer.Address.Country == country
orderby customer.Name, customer.Id);
return CustomerDTO.AsDTO(customers).ToArray();
}
}
這種方法的好處是,當你在SQL查詢,你會看到只有客戶ID,名稱和城市地址表會從數據庫中檢索。這是因爲AsDTO
方法將一個IQueryable
轉換爲另一個,允許LINQ to SQL在數據庫中執行整個操作。
我希望這給你一些你可以做的想法。當然,這是我對這個問題的看法,以及我在我的情況下發現的事情。
的LINQ to SQL是在DAL執行DB訪問,如果你想DAL和BLL之間分開。如果您的Web應用程序不太複雜(也從不打算切換數據庫後端),那麼您可以在沒有顯式DAL/BLL的情況下離開,並在代碼背後做所有事情。 LINQ to SQL對於只讀操作非常適用,但感覺實現寫操作需要多一點工作。
- 1. Linq to SQL數據源最佳實踐
- 2. 最佳實踐:LINQ to SQL用於數據訪問
- 3. LINQ更新程序 - 最佳實踐
- 4. 最佳實踐SQL
- 5. Db4O激活深度,Faq,Web應用程序的最佳實踐
- 6. 的LINQ to SQL通過BLL問題更新 - 最佳實踐
- 7. LINQ to SQL業務對象創建最佳實踐
- 8. 混合應用程序最佳實踐?
- 9. openshift - php應用程序 - 最佳實踐
- 10. Docker:Dockerize Tomcat應用程序 - 最佳實踐
- 11. Web應用程序工作流程的最佳實踐?
- 12. Enum to int最佳實踐
- 13. Web應用程序的事件監聽器最佳實踐
- 14. 的Windows應用程序:最佳實踐和模式(C#/ WPF/LINQ)
- 15. Facebook Canvas應用程序和獨立Web應用程序最佳實踐
- 16. Web應用程序用戶體驗行選擇最佳實踐
- 17. 基於Web的應用程序的ASP.NET和C#最佳實踐?
- 18. 最佳實踐Hibernate樂觀鎖定和Web應用程序
- 19. Backbone web應用程序體系結構 - 最佳實踐
- 20. 架構最佳實踐:Rails和移動/ Web應用程序
- 21. Web場應用程序部署的最佳實踐
- 22. 通過Web應用程序下載文件[最佳實踐]
- 23. 多個asp.net web應用程序的最佳實踐
- 24. Docker,Web應用程序靜態文件。最佳實踐?
- 25. 更新Go web應用程序的最佳實踐
- 26. 最佳實踐,以更新客戶端(GWT)Web應用程序
- 27. 在Amazon EC2上升級Web應用程序的最佳實踐
- 28. 部署.NET Web應用程序的最佳實踐
- 29. multipage/form mvc web應用程序的最佳實踐
- 30. ASP.NET Web應用程序中URL重定向的最佳實踐
感謝您的徹底迴應。我很害怕在表現層做數據訪問。我傾向於在數據層上進行大部分的排序操作,這不會成爲問題。我以前沒有聽說過DTO,聽起來像是要進一步研究的東西。 – derek 2010-05-07 22:37:51
DTO經常被認爲有很多開銷。在通過線路發送數據時(例如,在使用WCF或ASMX Web服務時),它們特別有用。例如,當您閱讀Dino Esposito的「Microsoft .NET:爲企業構建應用程序」時,您會注意到Dino認爲,當您在相同AppDomain的各個層之間傳輸對象時,他們通常會付出很多開銷。儘管他對此有所瞭解,但我仍然發現它們在該特定場景中非常有用,並且我發現技術改進時開銷會變得更小...... – Steven 2010-05-08 16:11:54
例如,新的C#語言構造(如自動屬性)可以更輕鬆地定義DTO和一個重構工具,如重構! Pro允許從LINQ查詢中的匿名類型定義自動生成DTO。 – Steven 2010-05-08 16:12:36