Entity Framework 4.1 - Как получить имя столбца для сгенерированного объекта poco - PullRequest
3 голосов
/ 10 октября 2011

Я использую Entity Framework 4.1, файл отображения edmx используется для генерации классов POCO с использованием шаблонов T4.

Как я могу получить имя столбца базы данных из контекста объекта для моих свойств объектов POCO(если это вообще возможно).

Я считаю, что сопоставление между свойствами и столбцами должно быть в одном из контейнеров:

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

Но я не смог определить связь междуCSpase и SSpace, похоже, CSSpase может выполнить эту работу, но этот контейнер пуст.

Есть идеи?

1 Ответ

0 голосов
/ 26 октября 2011

Я использовал смешанный подход, чтобы получить информацию о отображении (мы должны реализовать специальное устройство чтения / записи данных для определенных типов):

  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));
    }
    
...