C# 如何在实体框架中获取表的模式名?

C# 如何在实体框架中获取表的模式名?,c#,entity-framework,schema,entity,C#,Entity Framework,Schema,Entity,我使用用户模式分离技术来分离数据库中的表。您能告诉我如何在EntityFramework中获取EntitySet(表)的模式名吗?谢谢。用于DbContext和ObjectContext的扩展方法: public static class ContextExtensions { public static string GetTableName<T>(this DbContext context) where T : class { ObjectCon

我使用用户模式分离技术来分离数据库中的表。您能告诉我如何在EntityFramework中获取EntitySet(表)的模式名吗?谢谢。

用于DbContextObjectContext的扩展方法:

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;
    }
}
公共静态类contextensions
{
公共静态字符串GetTableName(此DbContext上下文),其中T:class
{
ObjectContext=((IOObjectContextAdapter)context).ObjectContext;
返回objectContext.GetTableName();
}
公共静态字符串GetTableName(此ObjectContext上下文),其中T:class
{
字符串sql=context.CreateObjectSet().ToTraceString();
正则表达式正则表达式=新正则表达式(“从(?.*)作为”);
Match=regex.Match(sql);
string table=match.Groups[“table”].Value;
返回表;
}
}
使用ObjectContext对象:

ObjectContext context = ....;
string table = context.GetTableName<Foo>();
DbContext context = ....;
string table = context.GetTableName<Foo>();
ObjectContext=。。。。;
string table=context.GetTableName();
使用DbContext对象:

ObjectContext context = ....;
string table = context.GetTableName<Foo>();
DbContext context = ....;
string table = context.GetTableName<Foo>();
DbContext上下文=。。。。;
string table=context.GetTableName();
更多信息请点击此处:


对于那些首先使用代码的人,架构名称在上下文的
OnModelCreating
覆盖中设置

public static readonly string DefaultSchemaName = "Entities";

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

    ...
因此,您应该能够从代码中的其他地方引用
DefaultSchemaName


如果您没有首先构建模型上下文和EF内容,那么这个答案就不那么明显了。

使用Entity Framework 6.1.3,您可以通过以下方式查询方案和表名:

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

其中T是实体的类型,而context是派生System.Data.Entity.DBContext的实例。

我找到了以下博客条目,解释了如何从metadataworkspace获取该信息:

下面是实现神奇效果的函数:

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;
}
公共静态字符串GetTableName(类型,DbContext-context)
{
变量元数据=((IObjectContextAdapter)上下文).ObjectContext.MetadataWorkspace;
//获取模型中包含实际CLR类型信息的部分
var objectItemCollection=((objectItemCollection)metadata.GetItemCollection(DataSpace.OSpace));
//从映射到CLR类型的模型中获取实体类型
var entityType=元数据
.GetItems(DataSpace.OSpace)
.Single(e=>objectItemCollection.GetClrType(e)=type);
//获取使用此实体类型的实体集
var entitySet=元数据
.GetItems(DataSpace.CSpace)
.Single()
.实体集
.Single(s=>s.ElementType.Name==entityType.Name);
//查找此实体集的概念模型和存储模型之间的映射
var mapping=metadata.GetItems(DataSpace.CSSpace)
.Single()
.EntitySetMappings
.Single(s=>s.EntitySet==EntitySet);
//查找实体映射的存储实体集(表)
变量表=映射
.EntityTypeMappings.Single()
.Fragments.Single()
.StoreEntitySet;
//从存储实体集中返回表名
返回(字符串)table.MetadataProperties[“table”].Value??table.Name;
}

现在这一定是一个老话题了,但是对于那些仍然潜伏在EF6+(而不是EF core)中的人来说,基于Rowan Miller当年同样优秀的博客,请查看我的方法,以展示关于给定实体的一些元信息

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),
    };
}
公共类DbTableMeta
{
公共字符串架构{get;set;}
公共字符串名称{get;set;}
公共IEnumerable键{get;set;}
}
公共静态DbTableMeta(此DbContext上下文,类型)
{
变量元数据=((IObjectContextAdapter)上下文).ObjectContext.MetadataWorkspace;
//获取模型中包含实际CLR类型信息的部分
var items=(ObjectItemCollection)metadata.GetItemCollection(DataSpace.OSpace);
//从映射到CLR类型的模型中获取实体类型
var entityType=元数据
.GetItems(DataSpace.OSpace)
.Single(p=>items.GetClrType(p==type);
//获取使用此实体类型的实体集
var entitySet=元数据
.GetItems(DataSpace.CSpace)
.Single()
.实体集
.Single(p=>p.ElementType.Name==entityType.Name);
//查找此实体集的概念模型和存储模型之间的映射
var mapping=metadata.GetItems(DataSpace.CSSpace)
.Single()
.EntitySetMappings
.Single(p=>p.EntitySet==EntitySet);
//查找实体映射的存储实体集(表)
变量表=映射
.EntityTypeMappings.Single()
.Fragments.Single()
.StoreEntitySet;
返回新的DbTableMeta
{
Schema=(字符串)table.MetadataProperties[“Schema”].Value??table.Schema,
名称=(字符串)table.MetadataProperties[“table”].Value??table.Name,
Keys=entityType.KeyMembers.Select(p=>p.Name),
};
}

用于截断同时需要表名和模式的表的示例

public void ClearTable<T>() where  T: class
    {
        var dbContext = (DbContext) _dbContext;
        
        var annotations = dbContext.Model.FindEntityType(typeof(T)).GetAnnotations().ToList();

        var tableName = annotations.First(c => c.Name == "Relational:TableName").Value.ToString();
        var schema = annotations.First(c => c.Name == "Relational:Schema").Value.ToString();

        dbContext.Database.ExecuteSqlRaw($"truncate table {schema}.{tableName}");

    }
public void ClearTable(),其中T:class
{
var dbContext=(dbContext)\u dbContext;
var annotations=dbContext.Model.FindEntityType(typeof(T)).GetAnnotations().ToList();
var tableName=annotations.First(c=>c.Name==“Relational:tableName”).Value.ToString();
var schema=annotations.First(c=>c.Name==“Relational:schema”).Value.ToString();
dbContext.Database.ExecuteSqlRaw($“truncate table{schema}.{tableName}”);
}

@M.Babcock schema代表@LadislavMrnka,我们的客户机将表分为不同的模式。有一个审计跟踪功能,记录表的每次更改。我想在identity中添加一列,该表属于哪个模式,并在选择时过滤审计跟踪记录