【问题标题】:Entity Framework 4.1 - How to get a name of a column for a generated poco objectEntity Framework 4.1 - 如何获取生成的 poco 对象的列名
【发布时间】:2011-10-10 13:42:37
【问题描述】:

我正在使用实体框架 4.1,一个 edmx 映射文件用于使用 T4 模板生成 poco 类。

如何从我的 poco 实体属性的对象上下文中获取数据库列的名称(如果可能的话)。

我认为属性和列之间的映射应该在其中一个容器中:

var container = objectContext.MetadataWorkspace
    .GetEntityContainer(objectContext.DefaultContainerName, DataSpace.CSpace);
...

但我无法识别 CSpase 和 SSpace 之间的链接,看起来 CSSpase 可以完成这项工作,但这个容器是空的。

有什么想法吗?

【问题讨论】:

  • CSSpace 是完全内化的。您需要进行非公共成员反射或阅读原始 csspace xml 以获取您需要的信息。
  • 我可以读取 edmx 文件,但这是我想避免的。您有如何入侵 CSSpace 的示例吗?
  • 我曾经采取非公开反射路线,但由于数据模型的差异,事情开始出现问题。我最终放弃了它,转而使用 xml 路由,这稍微不像 hack(我猜)。您不需要阅读 edmx 本身。 edmx 作为三个清单资源(ssdl、csdl 和 msl)嵌入到您的输出程序集中......因此您可以直接从这些资源中加载 xml。

标签: .net entity-framework poco


【解决方案1】:

我使用混合方法来获取映射信息(我们必须为某些类型实现自定义数据读取器/写入器):

  1. 首先获取 EntityType 对象以提取您的 POCO 类型的元信息:

    public static EntityType GetEntityTypeForPoco(this ObjectContext context, 
                                                             Type pocoEntityType)
    {
        EntityType entityType 
                 = context.MetadataWorkspace.GetItem<EntityType>
                   (pocoEntityType.FullName, DataSpace.OSpace);
    
        return (EntityType)context.MetadataWorkspace
               .GetEdmSpaceType((StructuralType)entityType);
    }
    
  2. 读取映射XML文档:这部分基本上是硬编码的,映射xml文档保存在edmx文件所在的程序集中,名为[your_edmx_file_name].msl

    currentMslSchemaDocument = new StreamReader(
                Assembly.GetExecutingAssembly().
                GetManifestResourceStream(CurrentMslSchemaDocumentName)
              ).ReadToEnd();
    
  3. 从 XML 文档读取属性到列的映射:

    var mappingFragments = MslSchemaDocument
    .Descendants(XName.Get(ElementNameEntityTypeMapping, NamespaceNameMsl))
    .Where(mp => (mp.Attributes(AttributeNameTypeName).Any() 
    && mp.Attribute(AttributeNameTypeName).Value == entityTypeModelName));
    
    if (mappingFragments.Count() == 0)
    {
        throw new Exception(String.Format("Entity mapping {0} is not found in the given schema stream", entityTypeModelName));
    }
    
    //theoretically could be several fragments mapping one entity ytpe to several table
    XElement mappingFragment = mappingFragments.First();
    
    string tableName = mappingFragment.Descendants(XName.Get(ElementNameMappingFragment, NamespaceNameMsl))
    .First().Attribute(AttributeNameStoreEntitySet).Value;
    
    List<KeyValuePair<string, string>> propertyColumnMappingList = new List<KeyValuePair<string, string>>();
    
    foreach (var xScalarProperty in mappingFragment.Descendants(XName.Get(ElementNameScalarProperty, NamespaceNameMsl)))
    {
       propertyColumnMappingList.Add(new KeyValuePair<string, string>(xScalarProperty.Attribute(AttributeNameName).Value,
                xScalarProperty.Attribute(AttributeNameColumnName).Value));
    }
    

【讨论】:

  • 我觉得一个人需要跳过这么多圈,只是为了获得一些基本的地图信息,EF 在整个路线上都使用它,这很荒谬。现在2年过去了。我很好奇是否有任何变化。
  • 据我所知,他们(微软)已承诺将其作为 API 的一部分提供,可能会附带新版本的开发工具。但老实说,我不再追踪这个问题,现有代码可以工作,这意味着库接口和行为或多或少是相同的。
猜你喜欢
  • 2011-07-31
  • 2011-12-26
  • 2011-11-11
  • 2011-12-05
  • 2011-04-18
  • 1970-01-01
  • 1970-01-01
  • 2011-11-16
  • 1970-01-01
相关资源
最近更新 更多