简体   繁体   English

带有实体框架的ASp.NET MVC:视图中的渴望和延迟加载

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

Is this code at view really make lazy loading and each time it hits the database? 视图中的这段代码是否真的使延迟加载以及每次访问数据库时都进行延迟加载? And if it is, is there a solution, and how can I know that if it hit database or not? 如果是的话,有没有解决方案,我怎么知道它是否命中数据库?

@{
    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>
    }
}

and my controller code is : 而我的控制器代码是:

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

        return View(moduleItems);
    }

You can use the System.Diagnostics.Trace class to see the queries that your LINQ is generating. 您可以使用System.Diagnostics.Trace类查看LINQ正在生成的查询。 Add this to wherever you use the dbcontext and call the controller method in debug: 将此添加到使用dbcontext的任何地方,并在debug中调用controller方法:

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

The SQL generated will be shown in the Output window in Visual Studio 2012. 生成的SQL将显示在Visual Studio 2012的“输出”窗口中。

No, there won't be lazy loading, because item.AlbumsLocs will be marked as loaded. 不,不会延迟加载,因为item.AlbumsLocs将被标记为已加载。 So the FirstOrDefault() will not trigger a new load attempt. 因此, FirstOrDefault()将不会触发新的加载尝试。 And you display a primitive property (which I assume Title is), so this won't load a reference. 并且显示一个原始属性(我假设Title是),因此不会加载引用。 You can easily verify this by monitoring the SQL statements. 您可以通过监视SQL语句轻松地验证这一点。

However, even though you're OK here, in general you should try to avoid constructs in views that potentially trigger lazy loading. 但是,即使您在这里还可以,但通常应该尝试避免在视图中构造可能触发延迟加载的构造。 For instance, when you forget the Include , lazy loading will become an issue and the view is far less scalable. 例如,当您忘记Include ,延迟加载将成为问题,并且视图的可伸缩性将大大降低。

So I would bring more elementary data to the view: 因此,我将更多基本数据带入视图:

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

(You should have langId available in the controller as well). (您还应该在控制器中使用langId )。

When the view gets more complex, work with view models, so you're in total control of when and where the data is fetched from the database. 当视图变得更加复杂时,请使用视图模型,这样您就可以完全控制从数据库中获取数据的时间和位置。

This also moves the responsibility of shaping the view data from the view to the controller, where it belongs. 这也将将视图数据成形的责任从视图移到了它所属的控制器。 (Or in a service, but not in the view). (或在服务中,但不在视图中)。

it may or it may not, depending on the model. 它可能会或可能不会,取决于型号。

to find out, use sql profiler and monitor the requests while running the view and you will find out whether or not it is using lazy loading. 要找到答案,请使用sql profiler并在运行视图时监视请求,您将发现它是否正在使用延迟加载。

to solve the problem you will have to include every property of the model thats being used on the view. 要解决该问题,您将必须包括视图中使用的模型的每个属性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM