2011-10-10 64 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