【问题标题】:Partially updating an entity in EF6部分更新 EF6 中的实体
【发布时间】:2015-08-04 16:00:27
【问题描述】:

我正在尝试弄清楚如何使用 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.Netanswer,我有点明白我必须做什么,但它并不能完全发挥作用。引用属性的逻辑失败。

考虑以下领域模型:

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 DbReferenceEntryrelation 没有任何迹象表明关系发生了变化。

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

【问题讨论】:

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


    【解决方案1】:

    Entity Framework validation with partial updates

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

    【讨论】:

    • 这很好,但它仍然无法消除未触及的引用属性的验证错误。我将更新 OP 以显示用例。
    • 请看我的更新 :) 欢迎任何进一步的想法!
    猜你喜欢
    • 2023-03-13
    • 1970-01-01
    • 2013-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多