实体框架不会检测导航属性的变化 [英] Entity Framework won't detect changes of navigation properties
问题描述
我有一个导航属性的检测变化麻烦:
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 $ C $ ?C> 不变
修改如果我打电话调用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屋!