我首先使用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;来控制加载。属性和包含 - 但我如何首先在数据库中进行此操作?
我从数据库加载后可以改变我的实体;但如果我稍后更新我的模型,他们就会重新创建。
答案 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();