Reputation: 20424
For a change logging function, I need to retrieve the primary key value of any entity. This will be written to the audit table together with the table name, and the changed property names and old and new values.
I could reflect the type of the particular entity and look for a [Key]
property. This would work in my case because I use code-first, attributes, and only single-column keys. But I'm not sure about the runtime performance of (uncached) reflection use.
Is there a more robust and "official" way to get the value of the primary key from an entity that is known to EF?
Please stay with the latest EF version (6.1.3). I cannot use solutions for EF 4/5 that access deprecated or removed functionality.
Code sample:
class MyEntity1
{
[Key]
public Guid KeyColumn { get; set; }
// ...
}
class MyEntity2
{
[Key]
public string EntityId { get; set; }
// ...
}
class MyContext : DbContext
{
public DbSet<MyEntity1> Entities1 { get; set; }
public DbSet<MyEntity2> Entities2 { get; set; }
public object GetEntityKey(object entity)
{
return ???(entity);
// Expected: The value of the property with [Key]
}
}
PS: I am using the following all-manual workaround, in case anybody is looking for the same solution. But it's not simple to maintain when new entities are added.
public object GetEntityKey<T>(T entity)
{
if (typeof(T) == typeof(MyEntity1))
{
return ((MyEntity1)(object)entity).KeyColumn;
}
if (typeof(T) == typeof(MyEntity2))
{
return ((MyEntity2)(object)entity).EntityId;
}
// Important: Makes you aware of new entities
throw new NotSupportedException("The specified entity type is not supported.");
}
Upvotes: 1
Views: 545
Reputation: 1058
I can't comment on the performance of using reflection for this but you can certainly find the PK of a given entity by using reflection and looking for the [Key] attribute (I'm assuming they all have this attribute):
public object GetEntityKey<T>(T entity)
{
return typeof(T).GetProperties().Where(x => Attribute.IsDefined(x, typeof(KeyAttribute))).Single().GetValue(entity);
}
Upvotes: 2