在实体框架中是否可以确定实体框架将在数据库中进行的实际更改/差异?
考虑一个例子,假设数据库中已经存在一些行,我们尝试再次添加它们。由于行已经存在,因此在数据库中所做的实际更改/差异为空。同样,如果我尝试 10 行,其中只有 3 行得到更新,那么我只想要那 3 行。
我试图用DbContext.ChangeTracker
它来实现相同的目标,但看起来它返回了我们尝试添加/更新/删除的所有行,而不管其中一些行是否已经存在于数据库中。有人也可以确认这种行为吗?
在实体框架中是否可以确定实体框架将在数据库中进行的实际更改/差异?
考虑一个例子,假设数据库中已经存在一些行,我们尝试再次添加它们。由于行已经存在,因此在数据库中所做的实际更改/差异为空。同样,如果我尝试 10 行,其中只有 3 行得到更新,那么我只想要那 3 行。
我试图用DbContext.ChangeTracker
它来实现相同的目标,但看起来它返回了我们尝试添加/更新/删除的所有行,而不管其中一些行是否已经存在于数据库中。有人也可以确认这种行为吗?
我在基本存储库中使用以下代码来获取修改后的属性名称和旧数据库值的字典。新值可以通过 TModel 对象本身轻松获取。
private Dictionary<string, object> GetModifiedProperties(TModel model)
{
var entry = Context.Entry(model);
// entry is detached.
// set entry to database entry and its CurrentValues to model values
if (entry.State == EntityState.Detached)
{
object key = model.GetType().GetProperty("Id").GetValue(model);
if (key == null)
{
throw new InvalidOperationException("The Entity you desire to update does not contain an Id value.");
}
var dbModel = Context.Set<TModel>().Find(key);
var dbEntry = Context.Entry(dbModel);
dbEntry.CurrentValues.SetValues(model);
entry = dbEntry;
//entry.State = EntityState.Modified;
}
var modifiedProps = new Dictionary<string, object>();
foreach (var propertyName in entry.CurrentValues.PropertyNames)
{
// copy only changed values to dict
var prop = entry.Property(propertyName);
if (prop.IsModified)
{
modifiedProps.Add(propertyName, prop.OriginalValue);
}
}
return modifiedProps;
}
可悲的是,我没有找到获得 Key 属性的优雅方法。但是“Id”对我有用。只有更改的属性应该出现在字典中。不完全是您想要的,而是可以使用的东西。
编辑:我为我的 DAL 使用工作单元模式。每个存储库都派生自我的基本存储库,也就是此代码的来源。update 方法触发 GetModifiedProperties() 方法。您可以编写这样的更新方法:
UnitOfWork.CutomerRepository.Update(Customer updated, out Dictionary<string, object> changedProps);