2011-05-24 58 views
7

我使用實體框架4.1與代碼優先的方法。我能夠獲得我的實體的存儲模型類型和列名稱:實體框架 - 從實體獲取表名

var items = context.ObjectContext.MetadataWorkspace.GetItems<EntityType>(DataSpace.SSpace); 

foreach (var i in items) 
{ 
    Console.WriteLine("Table Name: {0}", i.Name); 

    Console.WriteLine("Keys:"); 
    foreach (var key in i.KeyMembers) 
     Console.WriteLine("\t{0} ({1})", key.Name, key.TypeUsage.EdmType.FullName); 

    Console.WriteLine("Members:"); 
    foreach (var member in i.Members) 
     Console.WriteLine("\t{0} ({1})", member.Name, member.TypeUsage.EdmType.FullName); 
} 

我需要的是獲取實體映射到的真實表名。有不同的方式來指定(通過使用Fluent-API .ToTable(),DataAnnotation [TableAttribute])。

是否有任何常見的方法來實現這些信息?

回答

10

我已經找到了獲得表名的最簡單方法如下:

var tables = Context.MetadataWorkspace.GetItems(System.Data.Metadata.Edm.DataSpace.CSpace) 
       .Where(x => (x.MetadataProperties.Contains("NamespaceName") ? String.Compare(x.MetadataProperties["NamespaceName"].Value.ToString(), "Model", true) == 0 : false) 
       && !x.MetadataProperties.Contains("IsForeignKey") 
       && x.MetadataProperties.Contains("KeyMembers")); 

,將讓你的表的實體。

然後,你可以做以下提取名稱:

  foreach (var item in tables) 
      { 
       EntityType itemType = (EntityType)item; 
       String TableName = itemType.Name; 
      } 

注意如果您的複數化,你需要撤消的上下文。

1

有你可以得到EDM表名

public static string GetTableName<T>(this ObjectContext context) where T : EntityObject 
    { 
     var entities= context.MetadataWorkspace.GetItems(System.Data.Metadata.Edm.DataSpace.CSpace).Where(b => b.BuiltInTypeKind == BuiltInTypeKind.EntityType); 

     foreach (System.Data.Metadata.Edm.EntityType item in entities) 
     { 
      if(item.FullName==typeof(T).FullName) 
       return item.Name; 
     } 

     return String.Empty; 
    } 
+0

這不起作用,因爲它不返回架構名稱表 – NinjaCross 2013-09-14 17:29:46

9

EF 6.1,代碼優先的另一種方式:

public static string GetTableName<T>(this DbContext context) where T : class 
{ 
    ObjectContext objectContext = ((IObjectContextAdapter)context).ObjectContext; 
    return objectContext.GetTableName(typeof(T)); 
} 

public static string GetTableName(this DbContext context, Type t) 
{ 
    ObjectContext objectContext = ((IObjectContextAdapter)context).ObjectContext; 
    return objectContext.GetTableName(t); 
} 

private static readonly Dictionary<Type,string> TableNames = new Dictionary<Type, string>(); 

public static string GetTableName(this ObjectContext context, Type t) 
{ 
    string result; 

    if (!TableNames.TryGetValue(t, out result)) 
    { 
     lock (TableNames) 
     { 
      if (!TableNames.TryGetValue(t, out result)) 
      { 

       string entityName = t.Name; 

       ReadOnlyCollection<EntityContainerMapping> storageMetadata = context.MetadataWorkspace.GetItems<EntityContainerMapping>(DataSpace.CSSpace); 

       foreach (EntityContainerMapping ecm in storageMetadata) 
       { 
        EntitySet entitySet; 
        if (ecm.StoreEntityContainer.TryGetEntitySetByName(entityName, true, out entitySet)) 
        { 
         result = entitySet.Schema + "." + entitySet.Table;//TODO: brackets 
         break; 
        } 
       } 

       TableNames.Add(t,result); 
      } 
     } 
    } 

    return result; 
} 
+0

請考慮包括一些關於您的答案的信息,而不是簡單地發佈代碼。我們嘗試提供的不僅僅是「修復」,而是幫助人們學習。你應該解釋原始代碼中的錯誤,你做了什麼不同,以及爲什麼你的改變起作用。 – 2014-12-01 02:39:27

+2

我以爲「EF 6.1,code-first」是相當不錯的.... – 2015-04-16 10:51:01

+0

我不知道爲什麼,它不適用於我(使用db-first)。在這裏檢查我的答案。 http://stackoverflow.com/a/32871720/382515 – 2015-09-30 17:05:48