EF7 - 如何在更改之前从 DbSet 获取值
本文关键字:DbSet 获取 EF7 | 更新日期: 2023-09-27 18:32:13
我尝试获取存储在 DbSet 中的实体的值,该实体在被代码更改之前和保存之前。但是,当我尝试使用 LINQ Single
语句获取它时,我得到了更改的值。我正在使用 EF7。
代码如下:
DbSet<Entity> dbSet = Context.dbSet;
Entity ent = dbSet.Single(x => x.Id == id);
ent.FirstName = "New name";
Entity entityBeforeChange = dbSet.Single(x => x.Id == id); //here I want to get entity with old values, if that's important I just need to read it without modifying this instance
Context.SaveChanges();
希望我足够清楚,可以得到一些帮助
您可以从ChangeTracker
中获取任何实体的原始值。
var original = Context.ChangeTracker.Entries<Entity>().Single(x => x.Id == id);
var firstName = original.Property<string>("FirstName").OriginalValue;
这是我从审计库中使用的代码。
EF7
using (var ctx = new TestContext())
{
Entity ent = entity.Single(x => x.Id == id);
entity.FirstName = "New name";
context.ChangeTracker.DetectChanges();
// Find your entry or get all changed entries
var changes = context.ChangeTracker.Entries().Where(x => x.State == EntityState.Modified);
foreach (var objectStateEntry in changes)
{
AuditEntityModified(audit, objectStateEntry, auditState);
}
}
public static void AuditEntityModified(Audit audit, AuditEntry entry, EntityEntry objectStateEntry)
{
foreach (var propertyEntry in objectStateEntry.Metadata.GetProperties())
{
var property = objectStateEntry.Property(propertyEntry.Name);
if (entry.Parent.CurrentOrDefaultConfiguration.IsAudited(entry.ObjectStateEntry, propertyEntry.Name))
{
entry.Properties.Add(new AuditEntryProperty(entry, propertyEntry.Name, property.OriginalValue, property.CurrentValue));
}
}
}
EF6
using (var ctx = new TestContext())
{
Entity ent = entity.Single(x => x.Id == id);
entity.FirstName = "New name";
var entry = ((IObjectContextAdapter)ctx).ObjectContext.ObjectStateManager.GetObjectStateEntry(entity);
var currentValues = entry.CurrentValues;
var originalValues = entry.OriginalValues;
AuditEntityModified(originalValues, currentValues);
}
public static void AuditEntityModified(DbDataRecord orginalRecord, DbUpdatableDataRecord currentRecord, string prefix = "")
{
for (var i = 0; i < orginalRecord.FieldCount; i++)
{
var name = orginalRecord.GetName(i);
var originalValue = orginalRecord.GetValue(i);
var currentValue = currentRecord.GetValue(i);
var valueRecord = originalValue as DbDataRecord;
if (valueRecord != null)
{
// Complex Type
AuditEntityModified(valueRecord, currentValue as DbUpdatableDataRecord, string.Concat(prefix, name, "."));
}
else
{
if (!Equals(currentValue, originalValue))
{
// Add modified values
}
}
}
}
编辑:完整的源代码可以在我的GitHub存储库中找到:https://github.com/zzzprojects/EntityFramework-Plus
图书馆网站: http://entityframework-plus.net/
您可以从
上下文中Detach
实体。请记住,在更新另一个附加实体之前,必须将其从上下文中提取。
DbSet<Entity> dbSet = Context.dbSet;
Entity ent = dbSet.Single(x => x.Id == id);
Entity entityBeforeChange = dbSet.Single(x => x.Id == id);
Context.Entry(entityBeforeChange).State = EntityState.Detached; // severs the connection to the Context
ent.FirstName = "New name";
Context.SaveChanges();
您可以使用新的 DbContext,因为加载的实体缓存在已有的实体中。
Entity oldUnchanged;
using (var ctx = new YourDbContext())
{
oldUnchanged = ctx.Set<Entity>().Single(x => x.Id == id);
}