簡體   English   中英

使用帶有 Include() 的 LINQ to SQL 進行預加載

[英]Eager-loading using LINQ to SQL with Include()

我已經花了 2 天的時間來解決這個問題,但我似乎無法破解它(問題所在)。 相同的代碼運行良好,直到我添加了數據庫關系,而且我已經閱讀了很多關於延遲加載的內容。

我有兩個數據庫表,它們之間是 1:1 的關系。 PromoCode表跟蹤代碼,並有一個名為id的 PK 列。 CustomerPromo表有一個PromoId列,它鏈接到PromoCodeid 這兩個表沒有其他關系。 我在 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM