This question already has an answer here:
-
Get Database Table Name from Entity Framework MetaData
22 answers
I'm using the Entity Framework 4.1 with Code First approach. I'm able to get the storage model types and column names of my entities:
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);
}
What I need is to get the real table name the entity is mapped to. There are different ways to specify that (by using Fluent-API .ToTable(), DataAnnotation [TableAttribute]).
Is there any common way to achieve this information?
The Easiest way I have found to get table names is the following:
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"));
That will get you the table entities.
Then you can do the following to extract the name:
foreach (var item in tables)
{
EntityType itemType = (EntityType)item;
String TableName = itemType.Name;
}
Note if your pluralizing the context you will need to undo that.
EF 6.1, code-first:
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;
}
There is an other way you can get the EDM Table Name
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;
}