2012-06-11 48 views
0

我的擴展方法中的上下文和可用性存在問題。EF/LINQ:在擴展方法中獲取上下文,上下文應該是短暫的

基本上我使用UNITY,目前它爲我提供了一個新的DBContext實例,每次我調用我的數據層(將其注入到構造器中)。

我也放了一些擴展方法與IQueryable一起使用,數據層返回,所以我可以實際執行以下操作。

var result = dataLayer.GetItems().WithId(3) 

的withID是一個擴展方法,我有其他的擴展方法過,我需要做的,因爲表格/字段是不是在我的IQueryable上表的連接。

與此問題是,我的dbContext註冊每次給我一個新的實例,所以我得到一個錯誤形式的「不同的上下文.....」。

但是我應該配置Unity來爲我提供每次dbcontext的同一個實例,因爲dbcontext應該是SHORT LIVED。當然,如果我這樣做,我認爲我的問題將被修復,因爲數據層和擴展方法將使用相同的DBContext對象。

我已經使用EF 4.1與POCO類,沒有跟蹤,我有一個模型。因此,在另外一個表上進行連接的唯一方法是訪問我的dbcontext?

任何人有什麼建議我的選擇是什麼?

在此先感謝。

回答

2

坦率地說,具有依賴或影響數據上下文生命週期的擴展方法有點臭。擴展方法應該執行相對簡單的任務而不依賴於外部狀態,也不會產生副作用。它們適合功能性編程範例。 Queryable的擴展方法就是一個很好的例子。除了提供的參數外,它們不需要任何東西,永遠不會改變全局狀態或參數對象,並返回新的值或對象。

如果你想以這種方式使用擴展方法,你應該通過參數傳遞數據上下文。

但我不會用這種方式使用擴展方法。我寧願有一個具有(服務)方法的數據層,它允許您指定您需要的並返回IEnumerable(注意:不是IQueryable s)並完全封裝上下文。但這可能是您當前設計的重大改變。至少我只能通過Linq語句從數據層中獲取IQueryables。如果您需要連接或包含,請讓數據層根據您在我們的方法中詢問的數據應用它們。

只是一個建議:D

+0

非常感謝您的意見。所以我應該返回在數據層中使用連接的所有字段,然後在服務層我只需要調用我的擴展方法,我不需要在上下文中傳遞,因爲我需要在其中包含一個WHERE字段在領域..因此沒有加入?這是你所指的?如果我沒有弄錯......聽起來不錯。 – Martin

+0

通過返回IEnumerable vs IQueryable我會獲得什麼好處? – Martin

+0

至於IQueryable vs IEnumerable:IQueryable是一個「泄漏」的接口:它公開實現細節(它關注的是linq-to-xxx在它後面)。此外,它允許服務外的代碼深入影響發送到數據庫的查詢。這可能會影響性能和可測試性。這是你想讓數據層控制的東西。嘗試谷歌,你會看到很多關於這個問題的討論。 –

0

如果您必須在生命週期之間搭橋,則可以在處理創建和拆卸上下文的環境中創建一個包裝。 看看Mark Seemann's post

相關問題