[英]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 DbReferenceEntry
, relation
没有任何内容指示关系已更改。
在这种情况下,我可以检查哪些错误? 我还有其他需要特别处理的情况吗(例如一对多关系)?
@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.