2012-01-07 239 views
3

我使用用戶架構分離技術來分離數據庫中的表。你能告訴我如何在實體框架中獲取EntitySets(表)的Schema名稱嗎?謝謝。如何在實體框架中獲取表的模式名稱?

+0

爲什麼要這樣? – 2012-01-07 14:50:48

+0

@ M.Babcock架構代表http://msdn.microsoft.com/en-us/library/dd283095.aspx – 2012-01-07 17:13:28

+1

@LadislavMrnka,我們的客戶將表分成不同的架構。有一個審計追蹤功能可以記錄每個表格的變化。我想添加一列來標識表所屬的模式,並且可以在SELECT時篩選審計跟蹤記錄。 – 2012-01-07 17:20:30

回答

2

擴展方法的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; 
    } 
} 

使用ObjectContext的對象:

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

使用的DbContext對象:

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

更多信息她E:

Entity Framework: Get mapped table name from an entity

0

對於使用這些代碼優先,架構名稱設置在OnModelCreating覆蓋您的上下文的;

public static readonly string DefaultSchemaName = "Entities"; 

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

    ... 

所以你應該能夠從你的代碼的其他地方引用DefaultSchemaName

如果你沒有首先構建模型上下文和EF的東西,這個答案就不那麼明顯了。

-1

使用實體框架6.1.3,您可以查詢方案,並以下列方式將表名:

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

其中T是你的實體類型和上下文派生System.Data.Entity的實例.DBContext。

+1

你確定嗎?我認爲'Db '不存在。 – Balde 2016-11-08 21:13:48

+0

是的,我完全確定在使用MSSql的情況下!啊,當然T是你的功能的一個參數! – Diversity 2016-11-11 08:18:23

+0

那麼Db 函數[這裏](https://msdn.microsoft.com/en-us/library/system.data.entity.dbcontext(v = vs.113).aspx)在哪裏?沒有這樣的事情。 – Voo 2017-09-20 14:05:44

2

我發現下面的博客文章,介紹如何在從metadataworkspace信息獲取:

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

這必須是一個但對於那些仍然潛伏在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), 
    }; 
}