How to get the the Schama.TableName in EF 6 database-first?

此生再无相见时 提交于 2021-02-10 22:39:58

问题


I'm using EF 6 database-first.. I use this method to get the name of the table:

private static string GetTableName(ObjectContext context, Type entityType)
        {
            string entityTypeName = entityType.Name;

            EntityContainer container = context.MetadataWorkspace.GetEntityContainer(context.DefaultContainerName, DataSpace.CSpace);
            string tableName = (from meta in container.BaseEntitySets
                                where meta.ElementType.Name == entityTypeName
                                select meta.Name).First();
            return tableName;
        }

but it only returns the table name, I have 5 schemas in the database, every schema corresponds to a separate DbContext, so it might have identical names with different schema. So I need to return the full name of the table


回答1:


Basically you need Table and Schema properties of the EntitySet class. Unfortunately they are correctly populated only for the storage model, so in order to find it, you'll need to go through several model mappings.

Here is a sample method based on (in fact part of) the excellent post EF6.1 Get Mapping Between Properties and Columns` by Rowan Miller:

static EntitySet GetStorageEntitySet(ObjectContext objectContext, Type clrEntityType)
{ 
    var metadata = 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) == clrEntityType);

    // 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
    return mapping
        .EntityTypeMappings.Single()
        .Fragments.Single()
        .StoreEntitySet;
}

Sample usage in your case:

private static string GetTableName(ObjectContext context, Type entityType)
{
    var entitySet = GetStorageEntitySet(context, entityType);
    return entitySet.Schema + "." + entitySet.Table;
}

Update: It turns out that there are differences between Code First and Database First in regard to EntitySet Table and Name properties, so to get the table name generically I would suggest using:

var tableName = entitySet.Table ?? entitySet.Name;


来源:https://stackoverflow.com/questions/45398675/how-to-get-the-the-schama-tablename-in-ef-6-database-first

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!