实体框架TPH检测鉴别符列

时间:2018-11-01 15:38:49

标签: entity-framework entity-framework-6

我正在尝试实现自定义的Entity Framework迁移脚手架和sql生成器,它们将自动为discrimnator列添加索引。为了实现此解决方案,我想检测出区分符是哪一列,但是到目前为止,我还没有找到任何官方或非正式的方法来做到这一点。

我从检查ColumnModel对象的内容开始,这些对象作为参数传递给SqlServerMigrationSqlGeneratorCSharpMigrationCodeGenerator类的Generate()方法,但找不到任何指向这一点的东西。

是否有从发电机内部检测鉴别器的方法?还是可能来自上下文中包含的元数据?

1 个答案:

答案 0 :(得分:0)

在查看了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;
   }
 }

我已经使用默认的discriminator列和自定义的discriminator列测试了该解决方案,并且在两种情况下都可以正常工作。还对TPT和TPC以及实体拆分和表拆分进行了测试,并且在所有情况下都没有任何鉴别符,因此看起来工作正常。