如何在实体框架中获取表的架构名称
本文关键字:获取 实体 框架 | 更新日期: 2023-09-27 18:19:37
我使用用户模式分离技术来分离数据库中的表。你能告诉我如何在实体框架中获取实体集(表)的架构名称吗?谢谢
到目前为止,这肯定是一个老话题,但对于那些仍然潜伏在EF6+中的人(如在非EF核心中),基于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),
};
}
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>();
更多信息请点击此处:
实体框架:从实体中获取映射的表名
我发现了以下博客条目,解释了如何从元数据工作区获取这些信息:
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;
}
对于那些首先使用代码的人,模式名称是在上下文的OnModelCreating
覆盖中设置的;
public static readonly string DefaultSchemaName = "Entities";
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.HasDefaultSchema(DefaultSchemaName);
...
因此,您应该能够从代码中的其他地方引用DefaultSchemaName
。
如果你一开始没有构建模型上下文和EF的东西,这个答案就不那么明显了。
用于截断需要表名和模式的表的示例。
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}");
}
使用实体框架6.1.3,您可以通过以下方式查询方案和表名:
string tableNameWithScheme = context.Db<T>().Schema+"."+context.Db<T>().TableName;
其中,T是实体的类型,上下文是派生的System.Data.Entity.DBContext.