2014-10-29 185 views
0

我首先在SQLite和代码中使用实体框架6。 我遇到更新对象的问题。实体框架导航属性更新

我有一个 “记录” 对象

class Record { 

    public long Id; 
    public long StatusId 

    public virtual Statut Status; 
} 

等等 “状态” 对象。

我创造这样的

var newRecord = context.Records.Create(); 

Record对象虽然我没有在上下文中添加它,状态属性为null。

context.Records.Add(newRecord); 

现在,我在状态导航属性(ID为0的状态对象)中有一个状态对象。

但是,如果我改变StatusId为例如(此状态ID存在),状态属性不会更新。

实体框架不应该使用动态代理来检测这种变化吗?

感谢,

+0

你是什么意思的“默认状态”?如果这是一个非空的'Status'对象,如果你没有设置'Status'和'StatusId',它是如何到达那里的? – 2014-10-29 13:16:25

+0

StatusId不为空,所以默认情况下它的值是0.在我的数据库中,我有一个ID为0的状态对象。 – sbou 2014-10-29 13:20:38

回答

1

你观察到的行为是由实体框架的关系修正机制,这是由许多EF方法触发而这需要外键值,并参考(其中包括)一致性的护理过程中造成的。

关系修正是由相当大的number of methods触发的,但DbSet.Create()不是其中之一。因此,这里是发生了什么:

var newRecord = context.Records.Create(); 

Record被创建,其StatusId = 0无关系修正。

context.Records.Add(newRecord); 

新记录附加到上下文。现在EF执行关系修正。如果您监视SQL,则会看到从数据库中获取Status记录。

newRecord.StatusId = 1; 

不执行任何EF方法:没有关系修正,该Status对象仍然是一个与Id = 0

你现在能做些什么来得到正确的Status记录到newRecord要么执行一个触发关系修正的方法,或致电context.ChangeTracker.DetectChanges()

+0

感谢您的回答。调用DetectChanges似乎很重要。为什么代理不能在setter中做这个工作? – sbou 2014-10-29 13:54:13

+0

因为在大多数情况下你不需要这个。推荐使用EF的方法是创建上下文 - 执行 - 保存 - 处理上下文。然后,'StatusId'没有被覆盖,所以代理不能对它的setter做任何事情。 – 2014-10-29 14:01:25

+0

当我在http://msdn.microsoft.com/en-us/data/jj713564上阅读文档时。“同步FK和导航属性之间的变化”中的aspx我知道Entity框架应该为具有代理的POCO实体创建它。 – sbou 2014-10-29 14:04:14