Entity Framework TPH обнаруживает столбец дискриминатора - PullRequest
0 голосов
/ 01 ноября 2018

Я пытаюсь реализовать пользовательский каркас миграции Entity Framework и генератор sql, который бы автоматически добавлял индекс для столбца дискриминатора. Чтобы реализовать это решение, я хотел бы определить, какой столбец является дискриминатором, но до сих пор я не нашел никакого официального или неофициального способа сделать это.

Я начал с проверки содержимого объектов ColumnModel , которые передаются в качестве аргументов методу Generate () класса SqlServerMigrationSqlGenerator и CSharpMigrationCodeGenerator , но я не смог найти ничего, что указывало бы на это.

Есть ли какие-либо средства обнаружения дискриминатора внутри генераторов? Или, может быть, из метаданных, содержащихся в контексте?

1 Ответ

0 голосов
/ 19 января 2019

Посмотрев исходный код на Github и углубившись в EF, чем должен думать здравомыслящий человек, я думаю, что нашел решение, которое работает. Размещать это здесь на случай, если кому-то еще это понадобится:

 var metadata = ((IObjectContextAdapter)this).ObjectContext.MetadataWorkspace;
 var entityTypes = metadata.GetItems<EntityType>(DataSpace.SSpace);
 // These are the entity sets
 var entitySets = metadata.GetItems<EntityContainer>(DataSpace.CSpace).Single().EntitySets;
 foreach (var entitySet in entitySets)
 {
   // The mapping for the entity set
   var mapping = metadata.GetItems<EntityContainerMapping>(DataSpace.CSSpace).Single().EntitySetMappings.Single(s => s.EntitySet == entitySet);
   // If there is more than one mapping for the entity set...
   if (mapping.EntityTypeMappings.Count > 0)
   {
     // This shows that these mappings belong to a hierarchy
     var hierarchyMapping = mapping.EntityTypeMappings.SingleOrDefault(etm => etm.IsHierarchyMapping);
     if (hierarchyMapping == null)
       continue;
     // Get the conditions that contain the discriminator columns and values
     var conditions = mapping.EntityTypeMappings.SelectMany(etm => etm.Fragments.Single().Conditions).OfType<ValueConditionMapping>().ToList();
     if (conditions.Select(cc => cc.Column).Distinct().Count() > 1)
     {
       Debug.WriteLine($"{mapping.EntitySet.Name} has multiple mappings one of them being a hierachy mapping, but the fragments' conditions refer more than one distinct edm property");
       continue;
     }
     if (conditions.Select(cc => cc.Column).Distinct().Count() < 1)
     {
       Debug.WriteLine($"{mapping.EntitySet.Name} has a hierachy mapping, but none of the fragments' conditions are ValueConditionMappings");
       continue;
     }
     // This is the discriminator's name in the database
     var discriminatorColumn = conditions.First().Column.Name;
   }
 }

Я протестировал это решение со столбцом дискриминатора по умолчанию и с настраиваемым столбцом дискриминатора, и в обоих случаях оно работало нормально. Также протестировано с TPT и TPC, а также с разделением сущностей и таблицей, и во всех случаях не было выявлено никакого дискриминатора, поэтому, похоже, оно работает нормально.

...