2011-10-10 65 views
3

我正在使用实体框架4.1,一个edmx映射文件用于使用T4模板生成poco类。实体框架4.1 - 如何为生成的poco对象获取列的名称

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

我相信性能和列之间的映射应在容器之一:

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

但我无法确定CSpase和SSpace之间的纽带,它看起来像CSSpase可能做的工作,但是这个容器是空的。

任何想法?

+0

CSSpace完全内化。您需要执行非公共成员反射或阅读原始csspace xml以获取所需的信息。 – Jeff

+0

我可以阅读edmx文件,但这是我想避免的。你有一个如何入侵CSSpace的例子吗? – BanditoBunny

+2

我曾经采取非公开的反射路线,但事情开始打破数据模型的差异。我最终放弃了它,赞成xml路由,这是一个黑客(我猜)稍微少一点。您不需要阅读edmx本身。 edmx作为三个清单资源(ssdl,csdl和msl)嵌入在输出程序集中......因此您可以从这些资源中加载xml。 – Jeff

回答

0

我用了一个混合接洽以获得映射信息(我们要实现自定义数据读取器对某些类型/作家):

  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)); 
    } 
    
+1

我觉得这很荒谬,人们需要跳过这么多的箍环,才能得到EF沿途使用的一些基本映射信息。 2年过去了。如果有什么改变,我很好奇。 –

+0

据我所知,目前还没有,他们(微软)承诺将它作为API的一部分提供,或许会附带新版本的开发工具。但老实说,我不再追踪这个问题,现有的代码起作用,这意味着库的接口和行为或多或少是相同的。 – BanditoBunny