我试图写一个附加到实体框架代码第一,我需要一种方法来获得模型列的配置在运行时。例如,这是DbModelBuilder
在OnModelCreating
上设置的代码:
builder.Entity<NwdEmployee>()
.Property(n => n.ReportsToID).HasColumnName("ReportsTo");
一旦这样做了,EntityFramework知道我的属性的名称不同于表中的列名,但是我怎么能发现字符串"ReportsTo"
与运行时自己的ReportsToID
相关?理想情况下,我尝试编写如下方法:
public string GetMappedColumnName<TFrom>(DbContext context,
Func<TFrom, object> selector);
可以这样使用:
string mappedColumnName = GetMappedColumnName<NwdEmployee>(context,
x => x.ReportsToID);
我只是不知道在DbContext中找到映射的列名。它们是可访问的吗?
理论上是的。实际上,我不确定,因为通过简单的测试,我无法在运行时获得这些信息-我在调试器中看到它们,但我无法获得它们,因为我需要使用的类型是实体框架内部的。
理论。所有映射信息在运行时可用,但不能通过反射。它们存储在MetadataWorkspace
类的实例中,这绝对不是为直接使用而设计的,因为与该类的每次交互都需要在调试器中花费一些时间,然后才能找到如何获得所需的数据。这些数据不能通过DbContext API访问。您必须将DbContext
转换回ObjectContext
并访问MetadataWorkspace
。
ObjectContext objContext = ((IObjectContextAdapter)dbContext).ObjectContext;
GlobalItem storageMapping = objContext.MetadataWorkspace.GetItem<GlobalItem>("NameOfYourContextClass", DataSpace.CSSpace);
现在storageMapping
是System.Data.Mapping.StorageEntityContainerMapping
类的实例,即internal
。根据我的理解,这个类应该是MSL =存储和概念模型之间的映射的运行时表示。
如果你使用调试器,你可以探索实例,你会发现关于属性和列之间映射的信息(它嵌套得很深),所以你也可以使用反射来获取它们,但它是对你不拥有的类的非公共接口的反射,所以任何。net框架补丁/修复/更新都可能破坏你的应用。