Как получить имя схемы таблицы в Entity Framework? - PullRequest
3 голосов
/ 07 января 2012

Я использую технологию разделения пользовательских схем для разделения таблиц в базе данных.Не могли бы вы рассказать мне, как получить имена схем EntitySets (таблиц) в Entity Framework?Спасибо.

Ответы [ 5 ]

2 голосов
/ 25 апреля 2017

Я нашел следующую запись в блоге, которая объясняет, как получить эту информацию из пространства рабочих метаданных:

https://romiller.com/2014/04/08/ef6-1-mapping-between-types-tables/

Вот функция, которая творит чудеса:

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

    // Get the part of the model that contains info about the actual CLR types
    var objectItemCollection = ((ObjectItemCollection)metadata.GetItemCollection(DataSpace.OSpace));

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

    // 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 storage entity set (table) that the entity is mapped
    var table = mapping
        .EntityTypeMappings.Single()
        .Fragments.Single()
        .StoreEntitySet;

    // Return the table name from the storage entity set
    return (string)table.MetadataProperties["Table"].Value ?? table.Name;
}
2 голосов
/ 19 марта 2012

Методы расширения для DbContext и ObjectContext :

public static class ContextExtensions
{
    public static string GetTableName<T>(this DbContext context) where T : class
    {
        ObjectContext objectContext = ((IObjectContextAdapter) context).ObjectContext;

        return objectContext.GetTableName<T>();
    }

    public static string GetTableName<T>(this ObjectContext context) where T : class
    {
        string sql = context.CreateObjectSet<T>().ToTraceString();
        Regex regex = new Regex("FROM (?<table>.*) AS");
        Match match = regex.Match(sql);

        string table = match.Groups["table"].Value;
        return table;
    }
}

Использование объекта ObjectContext:

ObjectContext context = ....;
string table = context.GetTableName<Foo>();

Использование объекта DbContext:

DbContext context = ....;
string table = context.GetTableName<Foo>();

Подробнее здесь:

Entity Framework: получить имя сопоставленной таблицы от объекта

1 голос
/ 16 января 2018

Это, должно быть, старая тема на данный момент, но для тех, кто все еще прячется с EF6 + (как в не ядре EF), основываясь на том же превосходном блоге post Роуэн Миллер из прошлых дней, проверьте мой подход к появлению мета-информации о данной сущности

public class DbTableMeta
{
    public string Schema { get; set; }

    public string Name { get; set; }

    public IEnumerable<string> Keys { get; set; }
}


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

    // Get the part of the model that contains info about the actual CLR types
    var items = (ObjectItemCollection) metadata.GetItemCollection(DataSpace.OSpace);

    // Get the entity type from the model that maps to the CLR type
    var entityType = metadata
        .GetItems<EntityType>(DataSpace.OSpace)
        .Single(p => items.GetClrType(p) == type);

    // Get the entity set that uses this entity type
    var entitySet = metadata
        .GetItems<EntityContainer>(DataSpace.CSpace)
        .Single()
        .EntitySets
        .Single(p => p.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(p => p.EntitySet == entitySet);

    // Find the storage entity set (table) that the entity is mapped
    var table = mapping
        .EntityTypeMappings.Single()
        .Fragments.Single()
        .StoreEntitySet;

    return new DbTableMeta
    {
        Schema = (string) table.MetadataProperties["Schema"].Value ?? table.Schema,
        Name = (string) table.MetadataProperties["Table"].Value ?? table.Name,
        Keys = entityType.KeyMembers.Select(p => p.Name),
    };
}
0 голосов
/ 01 ноября 2016

Используя Entity Framework 6.1.3, вы можете запросить схему и имя таблицы следующим образом:

  string tableNameWithScheme = context.Db<T>().Schema+"."+context.Db<T>().TableName;

Где T - это тип вашей сущности и контекст экземпляра вашей производной System.Data.Entity.DBContext.

0 голосов
/ 28 июля 2015

Для тех, кто использует code-first, имя схемы задается в переопределении OnModelCreating вашего контекста;

public static readonly string DefaultSchemaName = "Entities";

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.HasDefaultSchema(DefaultSchemaName);

    ...

Так что вы должны иметь возможность ссылаться на DefaultSchemaName из любого места в вашем коде.

Этот ответ немного менее очевиден, если вы не создали контекст модели и EF.

...