[实体框架在不访问导航属性时会延迟加载相关的实体

问题描述 投票:0回答:2

我正在尝试使用EF 5(4.4)调试旧版MVC应用程序的性能问题。 SQL Server Profiler揭示了运行更多查询的方式。 EF似乎正在为该模型的每个相关实体生成查询。

现在听起来像是延迟加载。事实是,代码中的任何地方都没有引用导航属性(至少没有明确地引用)。

当我关闭上下文的延迟加载时,它会对其进行修复。另外,如果我返回的不是模型(例如,视图模型),则它会修复它。这是一个旧的,实现不佳的MVC应用-仍然应该使用viewmodels,所以很好。这些都是可接受的修复程序,但是我仍然想知道为什么正在发生。

我已经读过,序列化对象时可能会调用导航属性。那是这里发生的事吗?如果是这样,您能否解释为什么要序列化对象? (请注意,我对序列化的理解非常基础-基本上说的是here。)

这是一个例子:

Controller

    [HttpGet]
    public ViewResult StoreInfo(int id)
    {
        Store model = _posRepository.GetStore(id);

        return View(model);
    }

存储库

    public Store GetStore(int storeID)
    {
        return _dbContext.Store.Single(x => x.StoreID == storeID);
    }

模型

public partial class Store // highly simplified version
{           
    public int StoreID { get; set; }        
    public string StoreName { get; set; }        
    public Nullable<int> StateID { get; set; }          

    public virtual States State { get; set; } // lazy loaded
}

查看

// blank
c# asp.net-mvc entity-framework serialization lazy-loading
2个回答
0
投票

[我发现Glimpse(对于ASP.NET确实有用的诊断工具)正在访问其“元数据”选项卡的导航属性(请参阅我的other question,事实证明是相关的)。直到我禁用延迟加载,并检查了我发现它来自Glimpse的调用堆栈后,我才在nav属性上抛出NullReferenceException。由于EF模型直接传递给视图而不是视图模型,因此当填充元数据时,它正在访问nav属性,从而导致数据库查询。当我禁用Glimpse的“元数据”选项卡时,它解决了该问题。


0
投票

无需任何第三方使用,您可以通过匿名对象来实现。

var dataList = _dbContext.Store.Single(x => x.StoreID == storeID);var jsonData = dataList.Select(c => new {c.StoreID,c.StoreName,c.StateID,StateName = c.State?.Name,StateCode = c.State?.Code});

返回Json(jsonData,JsonRequestBehavior.AllowGet);

希望现在一切都好

© www.soinside.com 2019 - 2024. All rights reserved.