我一直在使用ASP.NET Core来构建API和数据访问我正在使用EF Core。在Stackoverflow和Google上进行冲浪,我找不到一种方法来仅使用存储库模式更新已修改的列。
有没有办法检查值是否有变化?
public virtual void Update(T entity)
{
// DbContext.Attach(entity);
var dbEntityEntry = DbContext.Entry(entity);
foreach (var property in dbEntityEntry.Properties)
{
var original = dbEntityEntry.OriginalValues.GetValue<object>(property.Metadata.Name);
var current = dbEntityEntry.CurrentValues.GetValue<object>(property.Metadata.Name);
if (original != null && !original.Equals(current))
dbEntityEntry.Property(property.Metadata.Name).IsModified = true;
}
}
我尝试像EF 6一样实现,但它抛出了InvalidCastException
System.InvalidCastException:'无法转换类型的对象 System.Func'2 [Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry,System.Int32]'键入'System.Func`2 [Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry,System.Object]'。'
我直接将从客户端收到的对象更新为动作控制器并更新它。
任何帮助都会非常感激。
由于
答案 0 :(得分:0)
如果您传入的原始T实体最初未从dbContext中检索到,则实体将不会被跟踪,因此EF本身将无法跟踪哪些属性已更改。
同样调用dbContext.Update会将实体上的所有属性标记为脏。
最好的建议是首先从DBContext中获取实体,然后使用像automapper这样的东西将传入的实体的属性映射到检索到的模型,然后调用DbContext.SaveChanges()这将只更新属性在地图期间发生了变化。 Automapper将仅处理双方存在的映射属性,如果需要更细粒度的控制,则可以配置映射。
下面的Psuedo代码:
public virtual void Update(T entity)
{
var existingEntity = DbContext.Entity.First(x => x.Id == entity.Id);
autoMapper.Map(entity, existingEntity);
DbContext.SaveChanges();
}