【问题标题】:Why is EF eagerly loading all navigation properties with EF Database first?为什么 EF 急切地首先使用 EF 数据库加载所有导航属性?
【发布时间】:2015-02-21 01:47:01
【问题描述】:

我首先使用 EF 数据库,因为我喜欢在 SQL Management Studio 中设计我的数据库,坦率地说,让 Visual Studio 直接从数据库创建所有实体非常容易,无需编写任何代码。

然而,我在 SQL Profiler 上注意到,每当我在结果集合上调用 ToList() 时,EF 都会急切地加载对象的所有相关实体。

假设我有一个这样的实体:

public class SomeEntity
{
  public string Name { get; set; }
  public IEnumerable<SomeOtherEntity> ListOfOtherEntites { get; set; }
}

然后我可以进行查询,获取这些实体的列表:

public IEnumerable<SomeEntity> GetAllOfTheSomeEntities(Guid customerId){
   return dbContex.SomeEntity.Where(x => x.CustomerId == customerId);
}

稍后在代码中,我想用这个列表做一些事情(例如在 MVC 中的控制器中),我会在查询中调用 ToList():

var list = repository.GetAllOfTheSomeEntities(customerId).ToList();

即使我从未在实体上使用属性“ListOfOtherEntites”,它仍然被加载到我的服务器内存中。

我知道我不必首先在代码中担心这一点,因为我可以使用“虚拟/非虚拟”属性和包含来控制加载 - 但是我如何首先在数据库中进行此操作?

从数据库加载实体后,我可以更改它们;但如果我稍后更新我的模型,它们只会被重新创建。

【问题讨论】:

  • 你怎么知道 ListOfOtherEntites 被加载到内存中?据我所知,在您尝试获取它之前不应该加载它(如果您启用了代理创建,则查询会发送到数据库,否则它将为空并且您无法从中获取值一次父对象加载到内存中)
  • 在我调用 ToList() 之后,我可以看到使用 SQL Profiler 并在我的代码中设置断点。立即从数据库中提取所有导航属性。
  • 你可以在 EF 中关闭延迟加载,并且可以使用 include 关键字来加载你想要加载的内容。
  • 非常感谢,阿兹哈尔。如果您可以发布一个答案,说明在哪里做,我会为您接受。 (可以找到在哪里做,但我想给你代表)
  • 显然这与延迟加载相反,我看不出关闭延迟加载如何解决这个问题。 @MichaelCleverly 显示执行急切加载的 SQL 可能是有益的

标签: c# asp.net-mvc entity-framework


【解决方案1】:

如果您遇到延迟加载问题,那么我可能会建议您在 EF 上下文中关闭延迟加载。

public class YourContext : DbContext
{
    public YourContext()
    {
        this.Configuration.LazyLoadingEnabled = false;
    }
}

然后您可以从这里使用 LINQ 的 .Include() 方法包含相关实体,如下所示:

var posts = context.Blogs.Include(b => b.Posts).ToList(); 

【讨论】:

    【解决方案2】:

    您需要将导航属性标记为virtual 以在实体框架中启用延迟加载。

    public class SomeEntity
    {
      public string Name { get; set; }
      public virtual IEnumerable<SomeOtherEntity> ListOfOtherEntites { get; set; }
    }
    

    简单地修改生成的代码不能解决问题吗?

    【讨论】:

    • 如果您阅读代码,我知道此解决方案。但是,首先使用数据库,一旦我再次从数据库更新我的模型,我在实体模型中的所有代码更改都将被覆盖。
    猜你喜欢
    • 1970-01-01
    • 2019-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-21
    • 1970-01-01
    • 2011-06-16
    • 2021-01-26
    相关资源
    最近更新 更多