Hel*_*rld 5 entity-framework entity-framework-6
我可以从以下示例中看到如何获取OSpace类型的表名:
https://lowrymedia.com/2014/06/10/ef6-1-mapping-between-types-tables-including-derived-types/
但是,如何从OSpace属性名称(即CLR类型属性)获取SSpace列名?
通过从相应的CSpace属性浏览MetadataProperties,我可以看到如果使用Fluid API或ColumnAttribute更改了包含列名的"Configuration"条目,但条目的值是EF的内部类.它可能吗?
我已经浏览了关于此主题的一些答案,但没有一个考虑Fluid API配置.
PS我正在寻找的特定属性是标量,如果这可以简化事情......
要获取列名,您必须首先EdmProperty在 \xe2\x80\x9c 结构空间\xe2\x80\x9d ( SSpace) 中获取与该列关联的名称。我在下面提供了执行此操作的代码。获得后EdmProperty,该列的名称很简单EdmProperty.Name:
string GetColumnName(DbContext context, PropertyInfo property) {\n return GetStructuralSpaceEdmProperty(context, property).Name;\n}\nRun Code Online (Sandbox Code Playgroud)\n\n这是基于一篇文章。那篇文章为您提供了足够的信息来一路映射到结构EntityType。我在最后添加了一些内容来进行实际的属性映射以获得EdmProperty代表列。正如文章所述,这些 API 需要 \xe2\x89\xa5EntityFramework-6.1。
EdmProperty GetStructuralSpaceEdmProperty(DbContext context, PropertyInfo property) {\n IObjectContextAdapter adapter = context;\n var metadata = adapter.ObjectContext.MetadataWorkspace;\n\n // First, you map the Object Space to the Conceptual Space.\n var objectItemCollection = (ObjectItemCollection)metadata.GetItemCollection(DataSpace.OSpace);\n var objectEntityType = metadata.GetItems<EntityType>(DataSpace.OSpace)\n .Single(oet => objectItemCollection.GetClrType(oet) == property.DeclaringType);\n // Note: we are assuming that CSpace and OSpace name their properties the\n // same instead of trying to use EF\xe2\x80\x99s own OSSpace mappings here.\n var conceptualEntityType = metadata.GetItems<EntityType>(DataSpace.CSpace)\n .Single(cet => objectEntityType.Name == cet.Name);\n var conceptualEdmProperty = conceptualEntityType.Properties\n .Single(ep => ep.Name == property.Name);\n\n // Then you map the conceptual space onto the structural space.\n var entitySet = metadata.GetItems<EntityContainer>(DataSpace.CSpace)\n .Single().EntitySets\n .Single(es => es.ElementType.Name == conceptualEntityType.Name);\n var entityMapping = metadata.GetItems<EntityContainerMapping>(DataSpace.CSSpace)\n .Single().EntitySetMappings\n .Single(esm => esm.EntitySet == entitySet);\n // The entity may be split to different tables or fragments.\n var fragments = entityMapping.EntityTypeMappings\n .SelectMany(etm => etm.Fragments);\n var propertyMappings = fragments.SelectMany(f => f.PropertyMappings);\n // Normal properties will be \xe2\x80\x9cScalarPropertyMapping\xe2\x80\x9d.\n // Depending on what information you are seeking or your\n // model, you may be interested in other PropertyMapping.\n var structuralSpaceProperty = propertyMappings\n .OfType<ScalarPropertyMapping>()\n .Single(pm => pm.Property == conceptualEdmProperty).Column;\n\n return structuralSpaceProperty;\n}\nRun Code Online (Sandbox Code Playgroud)\n\n请注意,一旦您进入EdmProperty结构空间,您就可以从中读取许多其他有用的属性。例如,对于 SQL Server,EdmProperty.IsUnicode将是truefor NVARCHAR/NCHAR和falsefor VARCHAR/CHAR类型,而该属性在概念空间中未设置为有用的值。
Alex D. James\xe2\x80\x99s 博客文章\xe2\x80\x9cTip 10 \xe2\x80\x94 如何理解实体框架术语\xe2\x80\x9d解释了一些没有意义的 API 术语他们自己。DataSpace.OSpace代表 \xe2\x80\x9cObject Space\xe2\x80\x9d,表示 .net POD 类。DataSpace.SSpace代表 \xe2\x80\x9cStructural Space\xe2\x80\x9d,可能以术语 \xe2\x80\x9cSQL\xe2\x80\x9d 中的 \xe2\x80\x9cstructed\xe2\x80\x9d 命名,因此表示它最直接描述的是后端数据库。DataSpace.CSpace代表 \xe2\x80\x9cConceptual Space\xe2\x80\x9d ,它似乎是一个中性空间,其中 \xe2\x80\x9cObject Space\xe2\x80\x9d 和 \xe2\x80\x9cStructural Space\xe2\ x80\x9d 可以映射到。DataSpace.OCSpace代表从对象空间到概念空间的映射。我们绕过此映射,因为我们假设对象空间中的属性名称与 .net 类型中的属性名称相同。DataSpace.CSSpace代表概念空间到结构空间的映射。我们使用此映射是因为模型可以通过Fluent API配置为使用不同的列名称或ColumnAttribute.
EF 的元数据 API 似乎假设 API 的使用者在一定程度上了解 EF 的内部结构。它不是以非常类型安全的方式制造的,无法帮助消费者。Enumerable.OfType<TResult>例如,我们必须使用get to 的事实ScalarPropertyMapping意味着我们必须知道期望集合ScalarPropertyMapping中包含实例。同样,该MetadataWorkspace.GetItems<T>()方法要求我们知道在元数据中可以找到的项目类型包括EntityType。因此,需要深入了解 EF 的内部结构或完整的示例,才能编写使用这些 API 映射部分的代码。
| 归档时间: |
|
| 查看次数: |
320 次 |
| 最近记录: |