Получить значение Discriminator из типа сущности в рабочей области метаданных - PullRequest
0 голосов
/ 28 декабря 2018

Есть ли способ получить значение дискриминатора для данного DbContext и объекта type, используя рабочее пространство метаданных?Я надеялся найти что-то, что работает примерно так https://romiller.com/2014/04/08/ef6-1-mapping-between-types-tables/.

Использование будет:

public class MyContext : DbContext
{
    public DbSet<Foo> Foo { get; set; }
}
public class FooBase
{
}
public class Foo : FooBase
{
}

public void Test()
{
    // should be "Foo"
    var discriminator = GetDiscriminatorValue(typeof(Foo), new MyContext());
}
public static string GetDiscriminatorValue(Type type, DbContext context)
{
    //...
}

1 Ответ

0 голосов
/ 28 декабря 2018

Я думаю, что смог решить эту проблему следующим способом.

public static string GetDiscriminatorValue(this DbContext context, Type type)
{
    var metadata = ((IObjectContextAdapter)context).ObjectContext.MetadataWorkspace;

    // Get the mapping between CLR types and metadata OSpace
    var objectItemCollection = ((ObjectItemCollection)metadata.GetItemCollection(DataSpace.OSpace));

    // Get the entity type from the model that maps to the CLR base type of the given type
    var entityType = metadata
            .GetItems<EntityType>(DataSpace.OSpace)
            .Single(e => objectItemCollection.GetClrType(e) == type.BaseType);

    // Get the entity set that uses this entity type
    var entitySet = metadata
        .GetItems<EntityContainer>(DataSpace.CSpace)
        .Single()
        .EntitySets
        .Single(s => s.ElementType.Name == entityType.Name);

    // Find the mapping between conceptual and storage model for this entity set
    var mapping = metadata.GetItems<EntityContainerMapping>(DataSpace.CSSpace)
            .Single()
            .EntitySetMappings
            .Single(s => s.EntitySet == entitySet);

    // Find the value condition (discriminator) that the given type is mapped
    var discriminator = mapping
        .EntityTypeMappings
        .Single(e => e.EntityType?.Name == type.Name)
        .Fragments
        .Single()
        .Conditions
        .OfType<ValueConditionMapping>()
        .Single();

    return (string)discriminator.Value;
}
...