我正在尝试编写Entity Framework Code First的附加组件,我需要一种在运行时获取模型列配置的方法。例如,这是OnModelCreating
的{{1}}代码设置:
DbModelBuilder
完成此操作后,EntityFramework知道我的属性名称与表中的列名不同,但是如何在运行时发现字符串builder.Entity<NwdEmployee>()
.Property(n => n.ReportsToID).HasColumnName("ReportsTo");
与"ReportsTo"
有关?理想情况下,我正在尝试编写如下方法:
ReportsToID
将使用如下:
public string GetMappedColumnName<TFrom>(DbContext context,
Func<TFrom, object> selector);
我只是不知道在DbContext中找到映射列名的位置。它们甚至可以访问吗?
答案 0 :(得分:4)
理论上是的。实际上我不确定,因为通过简单的测试,我无法在运行时获取这些信息 - 我在调试器中看到它们但我无法获取它们,因为我需要使用的类型是实体框架中的内部。
理论。所有映射信息都在运行时可用,但不能通过反射获得。它们存储在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框架补丁/修复/更新都会破坏您的应用程序。