2016-07-05 67 views
0

考虑以下(非常简单的)实体:实体框架懒加载不正确实体

public class User 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
} 

public class Answer 
{ 
    public int Id { get;set; } 
    public virtual User User { get; set; } 
    public string Text { get;set } 
} 

public class TeamMember 
{ 
    public int Id { get;set; } 
    public virtual User User { get; set; } 
    public string Role { get; set; } 
} 

在我的映射我可以设置用户罚款,但只要将下面的代码执行(持久保存任何更改之前,在DB)

if (teamMembers.Select(x => x.User).Contains(currentUser))

其中teamMembers是teamMembers的列表,currentUser是从数据库加载的用户实体,然后回答的用户属性设置为从数据库中前值。 我的理解是,因为我没有访问答案的用户属性之前它并没有被从数据库加载的是,这是发生了什么(它一直延迟加载?)。

,我可以通过读取用户之前,即使是在映射器设置它解决它,但我不能理解的是,为什么当我访问TeamMember的用户属性加载答案的用户属性和设置?这是预期的行为,因为两个实体都与同一个用户相关联(即在数据库中它们具有与外键相同的User_Id),并且在为TeamMembers加载时,EF试图聪明并填充引用它的其他实体, t已经加载了吗?

回答

0

的实体不存储/由具有对它们的引用,但保存自己收藏各自的元素缓存。

一旦加载通过teamMembers参考用户,它加载中...时期。当你从另一个元素/对象去引用它时,当它在内存中已经有了这个对象时,它将会很难再去加载它。

这是全部设计,它是有道理的...如果,例如,你想同时保存所有这些对象,它会首先创建用户,获取身份/密钥,然后保存其他对象使用生成的密钥引用它。

裁判:https://msdn.microsoft.com/en-us/data/hh949853.aspx#3

” ...的ObjectContext中会检查是否使用相同的密钥的实体 已经被加载到其ObjectStateManager如果与 相同的密钥的实体已经存在EF会。它包括在 查询的结果。虽然EF依然会发出对数据库查询, 这种行为可以绕过很多 多次物化实体的成本。”

+0

感谢您的答复,但它并没有完全回答我的问题(也许是不够明确)。假设我有两个用户,User1 {}和User2 {}。任何人都可以解释为什么当我从'User1 {}'设置'answer.User'的值为'User2 {}',然后不保存运行一个选择(例如'teamMembers.Select(x => x .User).Contains(currentUser)')在我的teamMembers集合中,然后将我的答案的User属性重置回User1 {}'? – msokrates

+0

用户2是否已经被保存到数据库中,还是只在该内存中? –

+0

我将User.User设置为User2(我从数据库中检索),但不保存此更改,但如果这就是您的意思。 – msokrates