5

I'm trying to write an add-on to Entity Framework Code First and I need a way to get the configuration of the model columns at run time. For example, this is the code setup on OnModelCreating by the DbModelBuilder:

builder.Entity<NwdEmployee>()
    .Property(n => n.ReportsToID).HasColumnName("ReportsTo");

Once this is done, EntityFramework knows that my property's name is different to the column name in the table, but how can I find that the string "ReportsTo" relates to ReportsToID myself at runtime? Ideally, I'm trying to write a method such as a following:

public string GetMappedColumnName<TFrom>(DbContext context, 
    Func<TFrom, object> selector);

Which would be used like:

string mappedColumnName = GetMappedColumnName<NwdEmployee>(context, 
    x => x.ReportsToID);

I just don't know where to find the mapped column names within the DbContext. Are they even accessible?

djdd87
  • 67,346
  • 27
  • 156
  • 195
  • i had similar problem. here is my solution: http://stackoverflow.com/questions/7008212/ef-code-first-get-entity-table-name-without-dataannotations – maxlego Nov 06 '11 at 20:56
  • I would be very interested to see your actual solution. Could you post it as another answer? It would be hugely helpful to me. – STW Apr 25 '12 at 19:55
  • There's a solution (somewhat) here: http://stackoverflow.com/a/20807366/861716. – Gert Arnold Dec 27 '13 at 20:31

1 Answers1

4

Theoretically yes. Practically I'm not sure because with simple test I wasn't able to get those information at runtime - I see them in debugger but I cannot get them because the type I need to use is internal in entity framework.

The theory. All mapping information are available at runtime but not through reflection. They are stored in the instance on MetadataWorkspace class which was definitely not designed for direct usage because every interaction with this class demands some time spend in debugger before you find how to get data you need. This data are not accessible through DbContext API. You must convert DbContext back to ObjectContext and access the MetadataWorkspace.

ObjectContext objContext = ((IObjectContextAdapter)dbContext).ObjectContext;
GlobalItem storageMapping = objContext.MetadataWorkspace.GetItem<GlobalItem>("NameOfYourContextClass", DataSpace.CSSpace);

Now storageMapping is instance of System.Data.Mapping.StorageEntityContainerMapping class which is internal. As I understand it this class should be runtime representation of MSL = mapping between storage and conceptual model.

If you use debugger you can explore the instance and you will find information about mapping between properties and columns (its quite deep nested) so you can also use reflection to get them but it is reflection on non public interface of classes you don't own so any .NET framework patch / fix / update can break your application.

Ladislav Mrnka
  • 360,892
  • 59
  • 660
  • 670
  • Once I had the `GlobalItem` entry point, the rest was easy! Thanks. – djdd87 Oct 28 '11 at 15:18
  • 2
    Why is it so complicated to get this information? EF is really bad when it comes to the performance of bulk inserts. You can use the custom EntityDataReader and SqlBulkCopy to get the job done, but only if you have these mappings. I don't want to hard-code these mappings over and over again just to have to do a manual fix whenever one of these mappings changes. I know, OR/M is not about bulk data. But consider imports from other systems where you have to do bulk inserts. What now? – Sebastian Weber Nov 22 '11 at 15:20
  • @Sebastian: Those are question for ADO.NET team. I cannot answer why it is so complicated but that is the way how MS APIs usually work - they are internally complicated and closed to any extension which wasn't originally supposed by MS. – Ladislav Mrnka Nov 22 '11 at 16:24
  • Is it possible that you give the path to access the column names ? all I see are the property names of the object and not the column names – Cedric Dumont May 07 '15 at 15:11
  • in fact this post helped me to get the name of the mapped column in ef : http://stackoverflow.com/questions/20161854/getting-mapped-column-names-of-properties-in-entity-framework – Cedric Dumont May 08 '15 at 07:26