简体   繁体   English

在EF6中部分更新实体

[英]Partially updating an entity in EF6

I'm trying to figure out how to smoothly do a partial update (basically a HTTP PATCH ) of an entity, using Entity Framework 6.0, but I'm stumped at the number of examples out there that don't seem to work for me (even those that aren't obviously for another version of EF). 我试图弄清楚如何使用Entity Framework 6.0平滑地对实体进行部分更新(基本上是HTTP PATCH ),但是我为其中似乎无法使用的示例感到困惑(即使那些显然不是针对另一个版本的EF的)。

What I'd like to accomplish: 我要完成的工作:

  • The entity is updated without having to load it first; 实体被更新,而不必先加载它; ie there's only one trip to the database 即只有一趟数据库
  • Only the properties that I touch are updated - others are left as is 只有我触摸的属性会更新-其他属性保持不变

The closest I've gotten is neatly described by this answer to a very similar question, and illustrated by the following code: 这个非常相似的问题的答案清楚地描述了我得到的最接近的答案 ,并由以下代码说明:

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();
    }
}

Now, this works for simple entities, but I'm getting entity validation errors because I have a couple of required properties and relations that are not updated and therefore not present in the attached entity. 现在,这适用于简单的实体,但是我遇到了实体验证错误,因为我有一些必需的属性和关系,这些属性和关系没有更新,因此在附加的实体中不存在。 As noted, I'd just like to ignore those. 如前所述,我只想忽略那些。

I've debugged and verified that context.Entry(entity).Property(e => e.Property).IsModified changes to true when that line is run, and that all the properties I never touch still return false for similar checks, so I thought EF would be able to handle this. 我已经调试并验证了context.Entry(entity).Property(e => e.Property).IsModified 。该行运行时context.Entry(entity).Property(e => e.Property).IsModified更改为true ,并且对于类似的检查,我从未接触过的所有属性仍然返回false ,因此我以为EF可以解决这个问题。

Is it possible to resolve this under the two constraints above? 是否可以在上述两个约束下解决此问题? How? 怎么样?


Update: 更新:

With LSU.Net 's answer I understand somewhat what I have to do, but it doesn't work fully. 使用LSU.Net答案,我在某种程度上了解了我必须做的事情,但是它不能完全起作用。 The logic fails for referential properties. 对于引用属性,逻辑失败。

Consider the following domain model: 请考虑以下域模型:

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

Now, if I try to update a MyEntity , I do the following: 现在,如果我尝试更新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();

In my custom validation method, overridden as in the answer below , the validation error on the required property OtherProperty is correctly removed, since it is not modified. 在我的自定义验证方法中,如下面的答案中所述 ,该方法已被覆盖,由于OtherProperty必需属性OtherProperty的验证错误,因此已正确删除。 However, I still get a validation error on the Related property, because entityEntry.Member("Related") is DbReferenceEntry , not DbPropertyEntry , and thus the validation error is not marked as a false error. 但是,我仍然在Related属性上收到验证错误,因为entityEntry.Member("Related") is DbReferenceEntry ,而不是DbPropertyEntry ,因此验证错误未标记为错误。

I tried adding a separate, analogous clause for handling reference properties, but the entityEntry doesn't seem to mark those as changed; 我尝试添加一个单独的类似子句来处理引用属性,但entityEntry似乎并未将其标记为已更改; with relation = member as DbReferenceEntry , relation doesn't have anything to indicate that the relationship is changed. 使用relation = member as DbReferenceEntryrelation没有任何内容指示关系已更改。

What can I check against for false errors in this case? 在这种情况下,我可以检查哪些错误? Are there any other cases I need to handle specially (one-to-many relationships, for example)? 我还有其他需要特别处理的情况吗(例如一对多关系)?

Entity Framework validation with partial updates 带有部分更新的实体框架验证

@Shimmy has written some code here to omit the validation logic for unmodified properties. @Shimmy在此处编写了一些代码,以省略未修改属性的验证逻辑。 That may work for you. 那可能对您有用。

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