How do I find which property of a class is the primary key of the Entity Framework Code First entity POCO?
Please note string matching for Id / class name + "Id" is a bad option. There must be some way to dig out the convention used by Entity Framework and reliably getting the key property.
Thanks in advance.
Use the ColumnAttribute or the HasKey method to specify an order for composite primary keys. In order to use composite keys, Entity Framework requires you to define an order for the key properties. You can do this by using the Column annotation to specify an order.
Code-first If chosen, it will create simple . cs file(s) which developers later modifies as per their requirement. Data-first If chosen, it will create a [name]. edmx file along with hierarchy of different files.
You can ask mapping metadata to get names of key properties (there can be more then one):
ObjectContext objectContext = ((IObjectContextAdapter)dbContext).ObjectContext; ObjectSet<YourEntity> set = objectContext.CreateObjectSet<YourEntity>(); IEnumerable<string> keyNames = set.EntitySet.ElementType .KeyMembers .Select(k => k.Name);
Once you have key names you can use reflection to access their values.
As you can see the approach reverts back to ObjectContext API because DbContext API is only for simple scenarios where you don't bother with such details like mapping metadata.
In case it helps anyone, I needed to be able to do this without the knowing the type beforehand (so I couldn't easily do CreateObjectSet<YourEntity>()
because I didn't know YourEntity
), so I was able to adapt @Ladislav 's solution into the following:
// variable "type" is a System.Type passed in as a method parameter ObjectContext objectContext = ((IObjectContextAdapter)this.context).ObjectContext; IEnumerable<string> retval = (IEnumerable<string>)objectContext.MetadataWorkspace .GetType(type.Name, type.Namespace, System.Data.Entity.Core.Metadata.Edm.DataSpace.CSpace) .MetadataProperties .Where(mp => mp.Name == "KeyMembers") .First() .Value;
Seems kind of odd that MetadataWorkspace.GetType
requires strings of the type name and namespace, instead of a System.Type, but that's the best I could find.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With