部分更新EF6中的实体

Tom*_*han 6 c# entity-framework entity-framework-6

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

我想要完成的事情:

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

我得到的最接近的答案是通过这个非常相似的问题的答案来描述的,并通过以下代码说明:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

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

我已经调试并验证了对该行运行时的context.Entry(entity).Property(e => e.Property).IsModified更改true,以及我从未触摸过的所有属性仍然返回false进行类似检查,因此我认为EF能够处理此问题.

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


更新:

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

考虑以下域模型:

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; }
}
Run Code Online (Sandbox Code Playgroud)

现在,如果我尝试更新a 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();
Run Code Online (Sandbox Code Playgroud)

在我的自定义验证方法中,如下面的答案中所覆盖,OtherProperty正确删除了必需属性上的验证错误,因为它未被修改.但是,我仍然在Related属性上获得验证错误,因为entityEntry.Member("Related") is DbReferenceEntry,DbPropertyEntry因此,验证错误未被标记为错误错误.

我尝试添加一个单独的,类似的句子来处理引用属性,但entityEntry似乎并没有标记为更改; with relation = member as DbReferenceEntry,relation没有任何迹象表明关系发生了变化.

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

LSU*_*Net 3

具有部分更新的实体框架验证

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

protected override DbEntityValidationResult ValidateEntity(
  DbEntityEntry entityEntry,
  IDictionary<object, object> items)
{
  var result = base.ValidateEntity(entityEntry, items);
  var falseErrors = result.ValidationErrors
    .Where(error =>
    {
      var member = entityEntry.Member(error.PropertyName);
      var property = member as DbPropertyEntry;
      if (property != null)
        return !property.IsModified;
      else
        return false;//not false err;
    });

  foreach (var error in falseErrors.ToArray())
    result.ValidationErrors.Remove(error);
  return result;
}
Run Code Online (Sandbox Code Playgroud)