繁体   English   中英

在EF6中部分更新实体

[英]Partially updating an entity in EF6

我试图弄清楚如何使用Entity Framework 6.0平滑地对实体进行部分更新(基本上是HTTP PATCH ),但是我为其中似乎无法使用的示例感到困惑(即使那些显然不是针对另一个版本的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();
    }
}

现在,这适用于简单的实体,但是我遇到了实体验证错误,因为我有一些必需的属性和关系,这些属性和关系没有更新,因此在附加的实体中不存在。 如前所述,我只想忽略那些。

我已经调试并验证了context.Entry(entity).Property(e => e.Property).IsModified 。该行运行时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; }
}

现在,如果我尝试更新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();

在我的自定义验证方法中,如下面的答案中所述 ,该方法已被覆盖,由于OtherProperty必需属性OtherProperty的验证错误,因此已正确删除。 但是,我仍然在Related属性上收到验证错误,因为entityEntry.Member("Related") is DbReferenceEntry ,而不是DbPropertyEntry ,因此验证错误未标记为错误。

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

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

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

@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;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM