Primary key properties don't necessarily have the
[Key]
attribute applied. They could be configured via the fluent API, or by convention.
Also remember that entities can have composite primary keys, where the key consists of more than one property.
Extracting the primary key properties is fairly easy:
Entity Framework 6:
private static IReadOnlyList<string> GetPrimaryKeyProperties(this IObjectContextAdapter context, Type entityType)
{
if (!context.ObjectContext.MetadataWorkspace.TryGetItem(entityType.FullName, DataSpace.OSpace, out EntityType dataType)) return Array.Empty<string>();
return dataType.KeyProperties.Select(p => p.Name).ToList();
}
public static IReadOnlyDictionary<string, DbPropertyEntry> ExtractPrimaryKey<TEntity>(this DbContext context, DbEntityEntry<TEntity> entry) where TEntity : class
{
var result = new Dictionary<string, DbPropertyEntry>(StringComparison.Ordinal);
foreach (string name in context.GetPrimaryKeyProperties(typeof(TEntity)))
{
result.Add(name, entry.Property(name));
}
return result;
}
Entity Framework Core:
public static IReadOnlyDictionary<string, PropertyEntry> ExtractPrimaryKey<TEntity>(this DbContext context, EntityEntry<TEntity> entry) where TEntity : class
{
IKey primaryKey = entry.Metadata.FindPrimaryKey();
return primaryKey.Properties.ToDictionary(p => p.Name, p => entry.Property(p.Name), StringComparer.Ordinal);
}