实体框架代码首先更新复杂类型的单个属性 [英] Entity Framework Code First Update a Single Property of a Complex Type

查看:133
本文介绍了实体框架代码首先更新复杂类型的单个属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个奇怪的行为。我想更新复杂类型的单个属性。当我指定要使用IsModified进行更新的属性时(某些属性为true,某些为false),我没有任何更新。如果我不指定复杂类型的属性,则会更新复杂属性的每个字段。

  public class MyEntity 
{
public MyComplexClass Property1 {get;组;
}

// ...下面的代码不起作用,其实它不会更新
var entityLocal = this.Set&MyEntity>()。 SingleOrDefault(d => d.Id == entity.Id);
if(entityLocal == null)
{
entityLocal = this.Set< MyEntity>()。
}
this.ChangeTracker.Entries< MyEntity>()。Single(d => d.Entity == entityLocal).State = EntityState.Modified;
this.Entry(entity).Property(s => s.Property1.SubProperty1).IsModified = true;
this.Entry(entity).Property(s => s.Property1.SubProperty2).IsModified = false; //这个接缝去除复杂类型的所有更新...?
this.SaveChanges();

产生:

  update [dbo]。[MyEntity] 
set @p = 0
其中(([Id] = @ 0))
/ pre>

如果我没有将SubProperty2的IsModified指定为false,我在SQL分析器中有以下内容:



[pre> update [dbo]。[MyEntity]
set [Property1_SubProperty1] = @ 0,[Property1_SubProperty2] = null
其中(([Id] = @ 1))

当某些属性指定IsModified时,没有更新? p>

编辑



经过几次尝试,我可以确认,如果我检查这两行,那是1属性一个复杂的类型设置为IsModified to False,整个复杂类型没有更新。

  var entry = DatabaseContext.Entry(entity ); 
var namesOfChangedProperties = entry.CurrentValues.PropertyNames.Where(p => entry.Property(p).IsModified).ToArray();

如果我设置为True任何属性,没有问题,但当1属性设置为false(IsModified) ,整个SubProperty不在namesOfChangedProperties变量内。



编辑2



我尝试使用ComplexProperty相同的结果。

  this.ChangeTracker.Entries< MyEntity>()。Single(d => d.Entity == entityLocal).State = EntityState.Modified; 
this.Entry(entity).ComplexProperty(s => s.Property1).Property(d => d.SubProperty1).IsModified = true;
this.Entry(entity).ComplexProperty(s => s.Property1).Property(d => d.SubProperty2).IsModified = false;
this.SaveChanges();


解决方案

这是EF修改跟踪方式的一个限制的复杂类型。 EF不跟踪属性级别的更改,而只跟踪整个对象是否被修改。这是一个限制,作为EF1的一部分内置,并没有被删除。一方面,对于那些想要更细粒度的变更跟踪的人来说,删除这个限制是很好的。然而,另一方面,通常认为将复杂对象视为不可变的价值类型的最佳实践。对于这样的值类型,整个对象总是被设置,这使得更细粒度的变化跟踪不那么有用。此外,更细粒度的更改跟踪不是一个非常常见的要求功能,所以EF团队很可能不会在此处工作。


I am having a weird behavior. I want to update a single property of a complex type. When I specify properties to be updated with IsModified (some property are to true and some to false) I have nothing updated. If I specify no property of the complex type, every field of the complex property are updated.

public class MyEntity
{
    public MyComplexClass Property1 { get; set; }
}

//... The code below doesn't work, in fact it update nothing
var entityLocal = this.Set<MyEntity>().Local.SingleOrDefault(d => d.Id == entity.Id);
if (entityLocal == null)
{
   entityLocal = this.Set<MyEntity>().Attach(entity);
}
this.ChangeTracker.Entries<MyEntity>().Single(d => d.Entity == entityLocal).State = EntityState.Modified;
this.Entry(entity).Property(s => s.Property1.SubProperty1).IsModified = true;
this.Entry(entity).Property(s => s.Property1.SubProperty2).IsModified = false;//This seam to remove all update of the complex type...?
this.SaveChanges();

This produce :

update [dbo].[MyEntity]
set @p = 0
where (([Id] = @0))

If I do not specify the IsModified to false of the SubProperty2, I have the following in the SQL profiler:

update [dbo].[MyEntity]
set [Property1_SubProperty1] = @0, [Property1_SubProperty2] = null
where (([Id] = @1))

How come when I specify "IsModified" on some property that nothing is updated?

Edit

After several try, I can confirm that if I check with those two lines that it's when 1 property of a complex type is set to IsModified to False that the whole complex type is no updated.

var entry = DatabaseContext.Entry(entity);
var namesOfChangedProperties = entry.CurrentValues.PropertyNames.Where(p => entry.Property(p).IsModified).ToArray();

If I set to True any property, no problem but when 1 property is set to false (IsModified), the whole SubProperty is not inside the namesOfChangedProperties variable.

Edit 2

I have try to use ComplexProperty with the same result.

this.ChangeTracker.Entries<MyEntity>().Single(d => d.Entity == entityLocal).State = EntityState.Modified;
this.Entry(entity).ComplexProperty(s => s.Property1).Property(d => d.SubProperty1).IsModified = true;
this.Entry(entity).ComplexProperty(s => s.Property1).Property(d => d.SubProperty2).IsModified = false;
this.SaveChanges();

解决方案

This is a limitation of the way EF does change tracking of complex types. EF doesn't track changes at the property level, but rather only tracks that the whole object is modified or not. This is a limitation that was built in as part of EF1 and has not been removed. On the one hand it would be good to remove this limitation for those people who do want more granular change tracking. However, on the other hand it is often considered best practice to treat complex objects as immutable "value types". For such value types the whole object is always set, which makes more granular change tracking less useful. Also, more granular change tracking is not a very commonly requested feature so it is unlikely that the EF team would work on it soon.

这篇关于实体框架代码首先更新复杂类型的单个属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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