【问题标题】:How to get the the Schama.TableName in EF 6 database-first?如何首先获取 EF6 数据库中的 Schema.Table 名称?
【发布时间】:2017-07-30 10:10:41
【问题描述】:

我使用的是 EF 6 数据库优先.. 我用这个方法来获取表名:

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;
        }

但它只返回表名,我在数据库中有 5 个模式,每个模式对应一个单独的DbContext,因此它可能具有不同模式的相同名称。所以我需要返回表的全名

【问题讨论】:

    标签: c# entity-framework ef-database-first


    【解决方案1】:

    基本上你需要EntitySet 类的TableSchema 属性。不幸的是,它们仅针对 storage 模型正确填充,因此为了找到它,您需要通过几个模型映射。

    这是一个基于 Rowan Miller 的优秀帖子 EF6.1 Get Mapping Between Properties and Columns` 的示例方法(实际上是其中的一部分):

    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;
    }
    

    您的案例中的示例用法:

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

    更新:事实证明 Code First 和 Database First 在 EntitySet TableName 属性方面存在差异,因此我建议一般获取表名使用:

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

    【讨论】:

    • 你的意思是entitySet.Name 吗?因为entitySet.Table 返回null
    • 我正在使用你的代码,它正确返回了架构名称,但表名称为空!
    • 好吧,你是对的,Code First 和 Database First 之间似乎有区别。您可以在您的情况下使用 Name 属性或更一般地使用更新中的代码。
    • 我想如果我给映射的实体起不同的名字,它会返回那个新名字!
    • 我已经用 edmx 模型试过了,它确实返回了表名。实际上,我发现了同一作者(顺便说一句是 EF 团队的成员)的另一篇文章,其中提出了相同的建议 - EF6.1 Mapping Between Types & Tables - 请参阅 GetTableName 方法实现。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-07
    • 2014-03-29
    相关资源
    最近更新 更多