簡體   English   中英

帶有實體框架的ASp.NET MVC:視圖中的渴望和延遲加載

[英]ASp.NET MVC with Entity Framework: eager and lazy loading in view

視圖中的這段代碼是否真的使延遲加載以及每次訪問數據庫時都進行延遲加載? 如果是的話,有沒有解決方案,我怎么知道它是否命中數據庫?

@{
    int langId = ViewBag.LangId;

    int i = 0;
    foreach (var item in Model)
    {
        i++;
        <tr class="@(i % 2 == 0 ? "even" : "odd")">
            <td>
                @Html.DisplayFor(modelItem => item.AlbumsLocs.FirstOrDefault(b => b.LanguageId == langId).Title)
            </td>
        </tr>
    }
}

而我的控制器代碼是:

public ViewResult Index()
    {
        var moduleItems = db.Albums.Include(x => x.AlbumsLocs).Where(a => a.AlbumVocId == id).ToList();

        return View(moduleItems);
    }

您可以使用System.Diagnostics.Trace類查看LINQ正在生成的查詢。 將此添加到使用dbcontext的任何地方,並在debug中調用controller方法:

#if DEBUG
           YourDbContext.Database.Log = x => Trace.WriteLine(x);
#endif

生成的SQL將顯示在Visual Studio 2012的“輸出”窗口中。

不,不會延遲加載,因為item.AlbumsLocs將被標記為已加載。 因此, FirstOrDefault()將不會觸發新的加載嘗試。 並且顯示一個原始屬性(我假設Title是),因此不會加載引用。 您可以通過監視SQL語句輕松地驗證這一點。

但是,即使您在這里還可以,但通常應該嘗試避免在視圖中構造可能觸發延遲加載的構造。 例如,當您忘記Include ,延遲加載將成為問題,並且視圖的可伸縮性將大大降低。

因此,我將更多基本數據帶入視圖:

db.Albums.Where(a => a.AlbumVocId == id)
         .Select(a => a.AlbumsLocs.FirstOrDefault(b => b.LanguageId == langId)
                       .Title)

(您還應該在控制器中使用langId )。

當視圖變得更加復雜時,請使用視圖模型,這樣您就可以完全控制從數據庫中獲取數據的時間和位置。

這也將將視圖數據成形的責任從視圖移到了它所屬的控制器。 (或在服務中,但不在視圖中)。

它可能會或可能不會,取決於型號。

要找到答案,請使用sql profiler並在運行視圖時監視請求,您將發現它是否正在使用延遲加載。

要解決該問題,您將必須包括視圖中使用的模型的每個屬性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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