2012-01-12 94 views
0

我想我遇到了一个错误,看起来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

尝试关闭延迟加载。 – cadrell0 2012-01-12 21:32:11

+0

您的实体如何定义?先编码?从数据库生成? – 2012-01-12 21:34:08

+0

@ cadrell0 - 我怕这不是一个选项,因为我需要延迟加载。 – Fabian 2012-01-12 21:52:59

回答

1

事实证明,它与删除和重新插入无关,而不是真的。它是那么明显......

我使用未即时加载,没有任何延迟加载功能的POCO插入...

我第二次查询了我期待相同的记录一个代理,但似乎POCO被EF缓存,这就是它返回的意思,仍然没有急切或懒惰的加载。

我可以通过确保EF无法从缓存中检索第二个查询,使用代理(var info = database.Info.Create())插入或在查询中包含成员(database.Info.Include(i => i.Member).First(i => i == 1))来解决此问题。

0

鉴于这种

var info = database.Info.First(i => i.ID == 1); 
Assert.AreEqual(1, info.MemberID); 

你不是比较info.ID这里info.MemberID? ID和MemberID实际上不一样吗?

而且,你不应该

database.Info.Remove(info); 

后使用.SaveChanges()?

此外,info没有.member可用,如果没有实例化。 MemberID是否与info.MemberId相关联?

+0

我明白这个混淆,会员也有ID 1(并且是成员存在于数据库中)。关于'.Remove()'后的'.SaveChanges()',那不幸的是没有任何区别。 – Fabian 2012-01-12 22:44:27