Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework code first. Find primary key

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.

like image 868
Sleeper Smith Avatar asked Aug 31 '11 07:08

Sleeper Smith


People also ask

What is meant by composite primary key in Entity Framework code First?

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.

How do I know if code first or database first?

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.


2 Answers

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.

like image 116
Ladislav Mrnka Avatar answered Oct 02 '22 07:10

Ladislav Mrnka


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.

like image 26
S'pht'Kr Avatar answered Oct 02 '22 06:10

S'pht'Kr