Entity Framework Core Extensions: Getting Primary Keys and Dirty Properties
Two simple hacks: finding the primary key values:
public static IDictionary<string, object> GetKeys(this DbContext ctx, object entity)
{
if (ctx == null)
{
throw new ArgumentNullException(nameof(ctx));
}
if (entity == null)
{
throw new ArgumentNullException(nameof(entity));
}
var entry = ctx.Entry(entity);
var primaryKey = entry.Metadata.FindPrimaryKey();
var keys = primaryKey.Properties.ToDictionary(x => x.Name, x => x.PropertyInfo.GetValue(entity));
return keys;
}
This returns a dictionary because some entities may have composite primary keys.
As for getting the dirty (modified) properties’ names for an entity:
public static IEnumerable<string> GetDirtyProperties(this DbContext ctx, object entity)
{
if (ctx == null)
{
throw new ArgumentNullException(nameof(ctx));
}
if (entity == null)
{
throw new ArgumentNullException(nameof(entity));
}
var entry = ctx.Entry(entity);
var originalValues = entry.OriginalValues;
var currentValues = entry.CurrentValues;
foreach (var prop in originalValues.Properties)
{
if (object.Equals(originalValues[prop.Name], currentValues[prop.Name]) == false)
{
yield return prop.Name;
}
}
}
Picking on the last one, if we wish to reset an entity to it’s original values:
public static void Reset(this DbContext ctx, object entity)Mind you, this one will not reset collections or references, just plain properties.
{
if (ctx == null)
{
throw new ArgumentNullException(nameof(ctx));
}
if (entity == null)
{
throw new ArgumentNullException(nameof(entity));
}
var entry = ctx.Entry(entity);
var originalValues = entry.OriginalValues;
var currentValues = entry.CurrentValues;
foreach (var prop in originalValues.Properties)
{
currentValues[prop.Name] = originalValues[prop.Name];
}
entry.State = EntityState.Unchanged;
}