部分更新EF6中的实体

时间:2015-08-04 16:00:27

标签: c# entity-framework entity-framework-6

我正在试图找出如何使用Entity Framework 6.0顺利进行实体的部分更新(基本上是HTTP PATCH),但是我很难看到那些不在似乎对我有用(甚至那些对于另一个版本的EF来说并不明显的人)。

我想要完成的事情:

  • 无需先加载实体即可更新实体;即只有一次数据库之旅
  • 只有我触摸的属性会更新 - 其他属性保持原样

我最接近的是this answer对一个非常相似的问题的巧妙描述,并通过以下代码说明:

public async Task UpdateMyEntity(int id, int? updatedProperty, string otherProperty)
{
    using (var context = new MyDbContext())
    {
        var entity = new MyEntity { Id = id };
        context.MyEntities.Attach(entity);

        if (updatedProperty != null) { entity.Property = updatedProperty.Value; }
        if (!string.IsNullOrEmpty(otherProperty) { entity.OtherProperty = otherProperty; }

        await context.SaveChangesAsync();
    }
}

现在,这适用于简单实体,但我得到实体验证错误,因为我有一些必需的属性和关系,这些属性和关系未更新,因此不会出现在附加实体中。如上所述,我只想忽略这些。

我已调试并验证context.Entry(entity).Property(e => e.Property).IsModified在运行该行时对true的更改,以及我从未触及的所有属性仍会返回false进行类似检查,所以我想EF能够处理这个问题。

在上述两个限制条件下是否可以解决这个问题?怎么样?

更新

使用LSU.Net answer我有点理解我必须做的事情,但它不能完全发挥作用。参考属性的逻辑失败。

考虑以下域模型:

public class MyEntity
{
    public int Id { get; set; }
    public int Property { get; set; }
    [Required]
    public string OtherProperty { get; set; }
    [Required]
    public OtherEntity Related { get; set; }
}

public class OtherEntity
{
    public int Id { get; set; }
    public string SomeProperty { get; set; }
}

现在,如果我尝试更新MyEntity,请执行以下操作:

var entity = new MyEntity { Id = 123 }; // an entity with this id exists in db
context.MyEntities.Attach(entity);

if (updatedProperty != null) { entity.Property = updatedProperty.Value; }

await context.SaveChangesAsync();

在我的自定义验证方法中,如the answer below中所覆盖的那样,正确删除了必需属性OtherProperty上的验证错误,因为它未被修改。但是,我仍然在Related属性上收到验证错误,因为entityEntry.Member("Related") is DbReferenceEntry而不是DbPropertyEntry,因此验证错误未标记为错误。

我尝试添加一个单独的类似子句来处理引用属性,但entityEntry似乎没有标记为已更改;使用relation = member as DbReferenceEntry时,relation没有任何内容表明关系已更改。

在这种情况下,我可以检查哪些错误错误?是否还有其他需要特殊处理的案例(例如一对多关系)?

1 个答案:

答案 0 :(得分:2)

Entity Framework validation with partial updates

@Shimmy在这里写了一些代码来省略未修改属性的验证逻辑。这可能对你有用。

Solid Color