我在以下类之间有两对一关系
public class SiteMember
{
public int SiteMemberID { get; set; }
public virtual List<FriendshipInvitation> InvitationsSent { get; set; }
public virtual List<FriendshipInvitation> InvitationsReceived { get; set; }
}
public class FriendshipInvitation
{
public int InvitingUserID { get; set; }
public SiteMember InvitingUser { get; set; }
public int InvitedUserID { get; set; }
public SiteMember InvitedUser{ get; set; }
}
然后在控制器中我有以下代码(从db加载一个SiteMember):
SiteMember sm = repoSiteMember.GetUserByName(User.Identity.Name);
此时
sm.InvitationsReceived.InvitingUserId = 1;
sm.InvitationsReceived.InvitingUser = null
然后我有以下行(从db加载所有SiteMembers):
IEnumerable<SiteMember> all = repoSiteMember.GetAll();
之后
sm.InvitationsReceived.InvitingUserId = 1
sm.InvitationsReceived.InvitingUser = proxy to SiteMember object.
我的问题是:这是正常行为吗?我很确定我可以用include语句“修复”空指针,但我发现从db加载所有元素实际上改变了对象的状态是很奇怪的。 (null =&gt; proxy)。代理人应该从一开始就在那里吗?
修改 只是为了确认,include语句确实解决了空引用的问题,但这不是问题。
DataContext.Members
.Include("InvitationsSent.InvitedUser")
.Include("InvitationsReceived.InvitingUser")
.FirstOrDefault(e => e.UserName == userName);
Edit2:现在包含的方法。
public SiteMember GetUserByName(string userName)
{
return base.DataContext.Members.FirstOrDefault(e => e.UserName == userName);
}
public IEnumerable<SiteMember> GetAll()
{
return base.DataContext.Members.ToList();
}
编辑3:您可能需要重新创建模型。
modelBuilder.Entity<FriendshipInvitation>()
.HasRequired(e => e.InvitedUser)
.WithMany(e => e.InvitationsReceived)
.HasForeignKey(e => e.InvitedUserID)
.WillCascadeOnDelete(false);
modelBuilder.Entity<FriendshipInvitation>()
.HasRequired(e => e.InvitingUser)
.WithMany(e => e.InvitationsSent)
.HasForeignKey(e => e.InvitingUserID);
modelBuilder.Entity<FriendshipInvitation>()
.HasKey(e => new { e.InvitingUserID, e.InvitedUserID, e.InvitationNo });
答案 0 :(得分:1)
是的,不同的行为是正常的,并且是因为 Relationship Fixup 而发生的。
当您只加载SiteMember
FirstOrDefault
InvitationsSent
时,两个集合InvitationsReceived
和virtual
将会在您访问它们时立即加载(或检查它们)调试器)因为它们被标记为FriendshipInvitation
并且将应用延迟加载。但是这些集合中的InvitingUser
不会延迟加载InvitedUser
或virtual
,因为这些导航属性不标记为SiteMember
。
说,您使用FirstOrDefault
加载的SiteMember
1收到了来自InvitationsReceived
2的邀请,但未发送任何邀请。因此,InvitationsSent
将包含一个元素,FriendshipInvitation
将为空。该元素 - InvitingUser
实体 - 将InvitedUser
设为2,将InvitingUser
设为1. null
在这种情况下将为virtual
,因为它不能被延迟加载(因为它不是SiteMember
)并且InvitedUser
2尚未加载到上下文中。 (SiteMember
但是SiteMember
1的动态代理,因为您已经加载了SiteMember
1,请参阅下一段。)
但是,如果您使用ToList()
加载所有 SiteMember
,ToList()
2将被加载到InvitingUser
2执行查询的上下文中。 1}}。 EF会自动将InvitingUser
2设置为已加载的实体,称为 Relationship Fixup 。延迟加载virtual
导航属性不,因为非InvitingUser
属性不支持延迟加载。
要获得一致的行为并且不依赖于关系修正,我建议您将InvitedUser
和virtual
导航属性标记为{{1}}。