我正在尝试实现自定义的Entity Framework迁移脚手架和sql生成器,它们将自动为discrimnator列添加索引。为了实现此解决方案,我想检测出区分符是哪一列,但是到目前为止,我还没有找到任何官方或非正式的方法来做到这一点。
我从检查ColumnModel对象的内容开始,这些对象作为参数传递给SqlServerMigrationSqlGenerator和CSharpMigrationCodeGenerator类的Generate()方法,但找不到任何指向这一点的东西。
是否有从发电机内部检测鉴别器的方法?还是可能来自上下文中包含的元数据?
答案 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以及实体拆分和表拆分进行了测试,并且在所有情况下都没有任何鉴别符,因此看起来工作正常。