EF7 - 如何在更改前从DbSet获取值

时间:2016-01-28 13:51:52

标签: c# asp.net entity-framework linq entity-framework-core

我尝试在代码更改之前和保存之前获取存储在DbSet中的实体的值。但是,当我尝试使用LINQ curl_setopt($ch, CURLOPT_CAINFO, dirname(__FILE__) . '\cacert.pem');语句时,我得到了更改的值。我使用EF7。

以下是代码:

Single

希望我足够清楚,可以得到一些帮助

4 个答案:

答案 0 :(得分:4)

您可以从ChangeTracker获取任何实体的原始值。

var original = Context.ChangeTracker.Entries<Entity>().Single(x => x.Id == id);
var firstName = original.Property<string>("FirstName").OriginalValue;

答案 1 :(得分:2)

这是我在审计库中使用的代码。

<强> 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/

答案 2 :(得分:1)

您可以使用新的DbContext,因为已加载的实体已缓存在您已有的实体中。

Entity oldUnchanged;
using (var ctx = new YourDbContext()) 
{
    oldUnchanged = ctx.Set<Entity>().Single(x => x.Id == id);
}

答案 3 :(得分:1)

您可以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();