[英]Eager-loading using LINQ to SQL with Include()
我已經花了 2 天的時間來解決這個問題,但我似乎無法破解它(問題所在)。 相同的代碼運行良好,直到我添加了數據庫關系,而且我已經閱讀了很多關於延遲加載的內容。
我有兩個數據庫表,它們之間是 1:1 的關系。 PromoCode
表跟蹤代碼,並有一個名為id
的 PK 列。 CustomerPromo
表有一個PromoId
列,它鏈接到PromoCode
表id
。 這兩個表沒有其他關系。 我在 SQL Server Management Studio 中生成了所有這些,然后從數據庫生成了模型。
為了讓事情稍微復雜一些,我在 WCF 數據服務中執行此操作,但我認為這不會產生影響(它在添加數據庫關系之前起作用)。 啟用日志記錄后,我總是在日志文件中收到一個帶有文本的異常:
在 Dispose 之后訪問的 DataContext。
我的函數當前返回表中的所有條目:
using (MsSqlDataContext db = new MsSqlDataContext())
{
// This causes issues with lazy-loading
return db.PromoCodes.ToArray();
}
我已經閱讀了許多文章/頁面/答案,他們都說要使用.Include()
方法。 但這對我不起作用:
return db.PromoCodes.Include(x => x.CustomerPromos).ToArray();
我也嘗試過“魔法字符串”版本:
return db.PromoCodes.Include("CustomerPromos").ToArray();
我設法開始工作的唯一代碼是:
PromoCode[] toReturn = db.PromoCodes.ToArray();
foreach (var p in toReturn)
p.CustomerPromos.Load();
return toReturn;
我試過在查詢中添加一個.Where()
條件,我試過.Select()
,我試過在.Include()
之后移動.Include()
.Where()
( 這個答案說要最后做,但是我認為這只是由於嵌套查詢)。 我已經閱讀了.Include()
會默默失敗的情況,畢竟我沒有接近。
我錯過了什么? 語法問題? 邏輯問題? 一旦我得到這個“簡單”的案例,我還需要嵌套Include
s(即如果CustomerPromo
表與Customer
有關系)。
編輯
包括所有相關代碼。 其余的要么是 LINQ to SQL,要么是 WCF 數據服務配置。 這就是全部:
[WebGet]
[OperationContract]
public PromoCode[] Test()
{
using (MsSqlDataContext db = new MsSqlDataContext())
{
return db.PromoCodes.Include(x => x.CustomerPromos).ToArray();
}
}
如果我直接通過瀏覽器調用它(例如http://<address>:<port>/DataService.svc/Test
),我會收到一條重置連接消息,並且必須查找 WCF 日志以找出“ DataContext accessed after Dispose.
”。 如果我通過網頁中的 AJAX 調用進行相同的查詢,則會收到帶有狀態error
的 AJAX error
(僅此而已!)。
當我實際上沒有任何要獲取的子數據時,我過早地發布了先前的答案。 當時我只對獲取父數據感興趣,這個答案奏效了。
現在,當我實際上也需要子數據時,我發現它並沒有完全起作用。 我發現這篇文章表明.Include()
他說Including()
但我不知道這是一個錯字)已被刪除,而正確的解決方案是使用DataLoadOptions
。 此外,我還需要啟用 Unidirectional Serialization 。
最重要的是,我不再需要DeferredLoadingEnabled
。 所以現在最終的代碼是這樣的:
using (MsSqlDataContext db = new MsSqlDataContext())
{
DataLoadOptions options = new DataLoadOptions();
options.LoadWith<PromoCode>(p => p.CustomerPromos);
db.LoadOptions = options;
return db.PromoCodes.ToArray();
}
設置Unidirectional Serialisation
它會很高興地返回一個父對象而不必加載子對象,或者顯式設置DeferredLoadingEnabled = false;
.
編輯:這並沒有完全解決問題。 在測試時沒有任何子數據,我也沒有嘗試使用它。 這只允許我返回父對象,它不返回子對象。 有關完整解決方案,請參閱此答案。
與我讀過的所有內容相反,答案不是使用.Include()
而是更改上下文選項。
using (MsSqlDataContext db = new MsSqlDataContext())
{
db.DeferredLoadingEnabled = false; // THIS makes all the difference
return db.PromoCodes.ToArray();
}
問題評論中發布的此鏈接(感謝@Virgil)暗示了答案。 但是我找不到訪問LazyLoadingEnabled
for LINQ to SQL 的方法(我懷疑它是用於 EntityFramework 的)。 此頁面表明 LINQ to SQL 的解決方案是DeferredLoadingEnabled
。
這里是指向DeferredLoadingEnabled上的 MSDN 文檔的鏈接。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.