Net Core: Find Primary Key of Entity Framework Core and Reflection

.net .net-core c# entity-framework entity-framework-core


How do I find Primary Key from an Entity Framework Core 2 Database Scaffold using Reflection .dll?

We need to find Primary Key Member given an EntityName, and return Primary Key Member as string. Conducted Reverse Scaffolding on Sql Server database .

modelBuilder.Entity<Product>(entity =>
    entity.HasKey(e => e.ProductInfoId)

Attempting Solution:

Trying to write next line code, given string Entity Name: "Product".

var assembly = Assembly.LoadFrom(@"C:\OnlineShoppingStore\bin\Debug\netcoreapp2.2\OnlineShoppingStore.dll");

assembly.GetTypes().Where(d=>d.Name = "OnlineStoreDbContext")

etc GetProperties().Where(e=>e.Name == "Product"))

Other Resource:

Prefer to do this with Reflection, rather than instantiating context since this is for code generation tool, will conduct for 10 db projects.

Generic Repository in C# Using Entity Framework

12/30/2019 8:11:07 PM

Accepted Answer

Expanding on suggestions from comments, you can instantiate the context in your code and invoke all EF model inspection APIs as outlined in Ivan's answer like so:

var assembly = Assembly.LoadFrom(@"C:\OnlineShoppingStore\bin\Debug\netcoreapp2.2\OnlineShoppingStore.dll");
var contextType = assembly.GetTypes().First(d => d.Name == "OnlineStoreDbContext");
var ctx = Activator.CreateInstance(contextType) as DbContext; // instantiate your context. this will effectively build your model, so you must have all required EF references in your project
var p = ctx.Model.FindEntityType(assembly.GetTypes().First(d => d.Name == "Product")); // get the type from loaded assembly
//var p = ctx.Model.FindEntityType("OnlineStoreDbContext.Product"); // querying model by type name also works, but you'd need to correctly qualify your type names
var pk = p.FindPrimaryKey().Properties.First().Name; // your PK property name as built by EF model

UPD: Forget thought experiments, it clearly is confusing. The method above does not require you to reference your other projects and requires no prior knowledge of types except for string names (which you have as it seems). When you instantiate your db context, the base class constructor in EF will process all your custom overrides and will return you a fully built model (i.e. all properties will be accounted for). Again, no reference will be required as long as you only use EF metadata API (which is available on base DBContext class). Hopefully that clarifies.

UPD2: following up on my IL Emit idea in comments. See the implementation and a bit more background in my blog. This enabled me to eliminate the exception (still have to have at least one DB Provider available though).

2/18/2020 9:26:22 AM

Related Questions


Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow