为什么EF急切地首先使用EF数据库加载所有导航属性?

时间:2014-12-22 22:42:28

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

我首先使用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();

即使我从不使用该物业&#34; ListOfOtherEntites&#34;在实体上,它仍然被加载到我服务器的内存中。

我知道我不必首先在Code中担心这个问题,因为我可以使用&#34;虚拟/非虚拟&#34;来控制加载。属性和包含 - 但我如何首先在数据库中进行此操作?

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

2 个答案:

答案 0 :(得分:3)

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

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

不是简单地修改生成的代码就可以解决问题吗?

答案 1 :(得分:1)

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

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

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

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