实体框架不会检测导航属性的变化 [英] Entity Framework won't detect changes of navigation properties

查看:107
本文介绍了实体框架不会检测导航属性的变化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个导航属性​​的检测变化麻烦:

I'm having trouble with detecting changes of a navigation property:

我的测试模型是这样的:

My testing model looks like this:

public class Person
{
    public int Id { get; set; }

    public string Name { get; set; }

    public virtual Address Address { get; set; }
}

public class Address
{
    public int Id { get; set; }

    public string Name { get; set; }
}



我已经创建并保存类型为Person的对象既名称和地址属性分配。我的问题是,如果我取人从数据库对象回来,我改变地址属性(例如为Null),则E.F.没有检测到的变化!
我的代码是这样的:

I've created and saved an object of type Person with both Name and Address properties assigned. My problem is that if I fetch the Person object back from the database and I change the Address property (ex. to Null) then the e.f. doesn't detect the change! My code is this:

using (var ctx = new EFContext())
{
    Person p = ctx.People.First();
    //p.Address IS NOT NULL!
    p.Address = null;
    var entry = ctx.Entry(p);
}



为什么 entry.State 不变

修改如果我打电话调用SaveChanges,记录正确保存(地址变NULL)

If I call the SaveChanges, the record is saved correctly (the Address become null)!

编辑2:我创建了外键属性作为比利建议,如果我检查在Visual Studio中Person对象的!状态会被修改..如果我不与调试器停止检查对象的值的状态不变。

Edit 2: I've created the foreign key property as billy suggested and if I inspect the Person object in visual studio the State is Modified.. if I don't stop with the debugger inspecting the object's values the state is Unchanged!

修改3:加载使用ctx.People.Include(X => x.Address)。首先()Person对象;解决这个问题。有没有办法避免调用包含并不断修改地址属性,而不是AddressId之一

Edit 3: Loading the Person object using ctx.People.Include(x => x.Address).First(); solves the problem. Is there a way to avoid calling Include and continue to modify the Address property instead of the AddressId one?

推荐答案

首先?您必须遵循@比利的建议使用包含。你的话的 p.Address不为空!的,因为你正在看 p.Address 中的调试器,从而触发延迟加载的是唯一真正的调试器,因此设置地址的变化来检测。在释放模式,或当你没有在调试器检查的属性您的代码将无法正常工作,并没有改变将被保存。

First of all: You MUST follow @billy's advice to use Include. Your remark "p.Address IS NOT NULL!" is only true because you are watching p.Address in the debugger and thereby triggering lazy loading in the debugger, so the change of setting the address to null is detected. In release mode or when you don't inspect the properties in the debugger your code wouldn't work and no changes would be saved.

所以,回答你的编辑3:否

So, the answer to your Edit 3 is: No.

二: VAR进入= ctx.Entry(p)返回实体美国的,你没有改变实体状态,而是一个的的关系状态的,或者更准确地说,你的删除的关系。你不能检查的关系状态用的DbContext API,但只能用的ObjectContext API:

Second: var entry = ctx.Entry(p) only returns entity states and you didn't change an entity state but instead a relationship state, or more precisely you deleted a relationship. You can't inspect relationship states with the DbContext API but only with the ObjectContext API:

Person p = ctx.People.Include(x => x.Address).First();
p.Address = null;
var objCtx = ((IObjectContextAdapter)ctx).ObjectContext;
var objentr = objCtx.ObjectStateManager.GetObjectStateEntries(EntityState.Deleted);



objentr 将有类型的输入 RelationshipEntry 现在:

objentr will have an entry of type RelationshipEntry now:

在这里输入的形象描述

EF将与实体状态条目一起考虑这个关系条目,当你调用的SaveChanges()并删除关系,即设置地址在数据库中的的外键列 NULL

EF will consider this relationship entry together with entity state entries when you call SaveChanges() and delete the relationship, i.e. set the Address foreign key column of the Person in the database to NULL.

关于编辑2:更改外键属性(这是模型中的标量属性)是实体本身的变化,因此实体状态将是修改在这种情况下。

About Edit 2: Changing a foreign key property (which is a scalar property in your model) is a change of the entity itself, so the entity state will be Modified in this case.

这篇关于实体框架不会检测导航属性的变化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆