繁体   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