C# 带实体框架的ASp.NET MVC:视图中的渴望和惰性加载
在视图中的代码是否真的会延迟加载,并且每次加载到数据库时都会延迟加载?若有,是否有解决方案,我如何知道它是否命中数据库C# 带实体框架的ASp.NET MVC:视图中的渴望和惰性加载,c#,asp.net-mvc,entity-framework,C#,Asp.net Mvc,Entity Framework,在视图中的代码是否真的会延迟加载,并且每次加载到数据库时都会延迟加载?若有,是否有解决方案,我如何知道它是否命中数据库 @{ int langId = ViewBag.LangId; int i = 0; foreach (var item in Model) { i++; <tr class="@(i % 2 == 0 ? "even" : "odd")"> <td>
@{
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>
}
}
它可能是也可能不是,取决于型号 要找到答案,请使用sql profiler并在运行视图时监视请求,您将发现它是否在使用延迟加载
要解决此问题,您必须包括视图中使用的模型的每个属性。您可以使用System.Diagnostics.Trace类查看LINQ生成的查询。将此添加到使用dbcontext并在调试中调用控制器方法的位置:
#if DEBUG
YourDbContext.Database.Log = x => Trace.WriteLine(x);
#endif
生成的SQL将显示在Visual Studio 2012的输出窗口中。否,不会延迟加载,因为
item.AlbumsLocs
将标记为已加载。因此,FirstOrDefault()
不会触发新的加载尝试。然后显示一个基本属性(我假设Title
是),这样就不会加载引用。您可以通过监视SQL语句轻松地验证这一点
然而,即使您在这里没有问题,一般来说,您应该尽量避免视图中可能触发延迟加载的构造。例如,当您忘记包含时,延迟加载将成为一个问题,视图的可伸缩性将大大降低
所以我会给视图带来更多的基本数据:
db.Albums.Where(a => a.AlbumVocId == id)
.Select(a => a.AlbumsLocs.FirstOrDefault(b => b.LanguageId == langId)
.Title)
(控制器中也应该有可用的langId
)
当视图变得更复杂时,使用视图模型,这样您就可以完全控制从数据库中获取数据的时间和地点
这也将塑造视图数据的责任从视图转移到它所属的控制器。(或在服务中,但不在视图中)。您应该使用针对实体框架的探查器,该探查器可以向您显示它生成的流量和查询。您使用的是什么数据库?Microsoft SQL Server有一个内置的分析工具,可以在进行数据库查询时向您显示SQL文本。我怀疑其他数据库可能也有类似的工具。谢谢你的帮助,但是你能知道查看中的代码是否每次都被数据库命中吗?谢谢你的帮助,我会尝试一下,但是如果你注意到我控制器上的代码,我会包括“AlbumsLocs”以防止延迟加载,但我需要表达我的观点,以获得我想要的特定元素,这可能是另一个属性导致的,甚至可能是“AlbumsLocs”中的属性
db.Albums.Where(a => a.AlbumVocId == id)
.Select(a => a.AlbumsLocs.FirstOrDefault(b => b.LanguageId == langId)
.Title)