我想我遇到了一个错误,看起来EF在删除并重新插入实体后没有很好地处理引用。我已经设法使用下面的代码重现它(假设所有断言都通过,除了我在评论中谈到的那个):
var database = new TestEntities();
// select and delete the info record
var info = database.Info.First(i => i.ID == 1);
Assert.AreEqual(1, info.MemberID);
// when i uncomment the line below the last Assert fails
// Assert.IsNotNull(info.Member);
database.Info.Remove(info);
// add it again and persist it to the database
database.Info.Add(new Info {
ID = 1,
MemberID = 1
});
database.SaveChanges();
// should not be null ? EDIT: i guess i understand this becoming null
Assert.IsNull(info.Member);
// and even here its still null
info = database.Info.First(i => i.ID == 1);
Assert.IsNull(info.Member);
谁能告诉我这里发生了什么?
编辑:
我的实体首先使用数据库生成,使用DbContext / POCO生成器生成。
public partial class Member
{
public Member()
{
this.Info = new HashSet<Info>();
}
public int ID { get; set; }
public string Name { get; set; }
public virtual ICollection<Info> Info { get; set; }
}
public partial class Info
{
public int ID { get; set; }
public int MemberID { get; set; }
public virtual Member Member { get; set; }
}
答案 0 :(得分:1)
事实证明它与删除和重新插入无关,而不是真的。这是如此明显......
我使用POCO进行插入,该POCO没有急切加载且没有任何延迟加载功能......
我第二次查询相同的记录时,我期待一个代理,但似乎POCO被EF缓存,这就是它返回的意思仍然没有急切或懒惰的加载。
我可以通过确保EF不从缓存中检索第二个查询,使用代理(var info = database.Info.Create()
)插入或在查询中包含成员(database.Info.Include(i => i.Member).First(i => i == 1)
)来修复它。
答案 1 :(得分:0)
鉴于此
var info = database.Info.First(i => i.ID == 1);
Assert.AreEqual(1, info.MemberID);
你不是在这里将info.ID与info.MemberID进行比较吗? ID和MemberID实际上可能不同吗?
另外,你不应该在
之后使用.SaveChanges()database.Info.Remove(info);
此外,如果没有实例化,则info不具有.member可用。会员ID是否等于info.MemberId?