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没有任何迹象表明关系发生了变化.
在这种情况下,我可以检查哪些错误错误?是否还有其他需要特殊处理的情况(例如一对多关系)?
@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)