我很難確定處理此問題的最佳方法...使用實體框架(和L2S),LINQ查詢返回IQueryable。我已閱讀關於DAL/BLL是否應返回IQueryable,IEnumerable或IList的各種意見。假設我們使用IList,那麼查詢立即運行,並且該控件不會傳遞到下一層。這使得單元測試更容易,等等。你失去了在更高級別上優化查詢的能力,但是你可以簡單地創建另一個方法,允許你改進查詢並仍然返回IList。還有更多的優點/缺點。到現在爲止還挺好。IQueryable和延遲加載
現在來實體框架和延遲加載。我在.NET 4/VS 2010使用POCO對象與代理人在表示層我做的:
foreach (Order order in bll.GetOrders())
{
foreach (OrderLine orderLine in order.OrderLines)
{
// Do something
}
}
在這種情況下,GetOrders()返回的IList所以它返回到PL之前立即執行。但在接下來的foreach中,你有懶惰的加載,它執行多個SQL查詢,因爲它獲取所有OrderLines。所以基本上,PL在錯誤的層中「按需」運行SQL查詢。
有沒有什麼明智的方法可以避免這種情況?我可以關閉懶惰的加載,但那麼每個人都抱怨EF1沒有這個「特徵」有什麼意義?我承認它在很多情況下非常有用。所以我看到幾個選項:
- 以某種方式刪除實體中的所有關聯並添加方法以返回它們。這違背了默認的EF行爲/代碼生成,並且使得難以執行一些組合(多個實體)LINQ查詢。這似乎是一個倒退。我投不到。
- 如果我們有延遲加載,這使得它很難單元測試,然後一路走,並返回IQueryable。你會有更多的控制層次。我仍然認爲這不是一個好的選擇,因爲IQueryable將您與L2S,L2E或您自己的IQueryable的完整實現聯繫在一起。延遲加載可以「按需」運行查詢,但不會將您與任何特定的界面綁定。我投不到。
- 關閉延遲加載。您必須手動處理您的關聯。這可以通過加載的.Include()來進行。我在某些特定情況下投贊成票。
- 保持IList和延遲加載。我在很多情況下投贊成票,只是由於其他人的麻煩。
還有其他的選擇或建議嗎?我還沒有找到真正讓我信服的選項。
你沒有涵蓋「從UI層延遲加載/ SQL執行」,但仍幫助。我認爲最後一段代碼與我所尋找的最接近。看起來你有1)易用性,2)封裝/ SoC /單元可測試/等等,3)使用高級功能(急切加載等)的能力。選擇兩個。你不能擁有全部三個。無論如何,感謝您的幫助。 – 2010-05-10 12:09:46