To get database table name on Entity framework 4.0 I do:
ObjectSetInstance.EntitySet.ToString()
Is there a way to do this on Entity Framework 4.1?
To get database table name on Entity framework 4.0 I do:
ObjectSetInstance.EntitySet.ToString()
Is there a way to do this on Entity Framework 4.1?
Extension methods for DbContext and 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;
}
}
Using a ObjectContext object:
ObjectContext context = ....;
string table = context.GetTableName<Foo>();
Using a DbContext object:
DbContext context = ....;
string table = context.GetTableName<Foo>();
More info here:
As of EF6.1, the solution explored in this article shows how to use the newly exposed metadata to accomplish this, should not require the database to be initialized or depend on what method was used to set the table name.
public static string GetTableName<T>(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) == typeof(T));
// 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;
}
Try something like this:
string name = (context as IObjectContextAdapter).ObjectContext.CreateObjectSet<MyClass>().EntitySet.Name;
You can try something like this.
private string GetTableName(Type type)
{
var tableAttribute = type.GetCustomAttributes(false).OfType<System.ComponentModel.DataAnnotations.TableAttribute>().FirstOrDefault();
return tableAttribute == null ? type.Name : tableAttribute.Name;
}
You can call this string like this.
var tableName = GetTableName(entityType.FirstOrDefault());
Please see the below link for further info. Link
I also found that CreateObjectSet() doesn't quite do the job, particularly when getting column names for use in SqlBulCopy(). The following code for getting the EntitySet seems to work better,
private EntitySet GetEntitySet<T>(DbContext context)
{
var type = typeof(T);
var entityName = type.Name;
var metadata = ((IObjectContextAdapter)context).ObjectContext.MetadataWorkspace;
IEnumerable<EntitySet> entitySets;
entitySets = metadata.GetItemCollection(DataSpace.SSpace)
.GetItems<EntityContainer>()
.Single()
.BaseEntitySets
.OfType<EntitySet>()
.Where(s => !s.MetadataProperties.Contains("Type")
|| s.MetadataProperties["Type"].ToString() == "Tables");
var entitySet = entitySets.FirstOrDefault(t => t.Name == entityName);
return entitySet;
}
To get the table name, there's two other methods I use instead of EntitySet.Name which returns the singular rather than pluralized name.
public string GetTableName<T>(DbContext context)
where T: class
{
var entitySet= GetEntitySet<T>(context);
if (entitySet == null)
throw new Exception("Unable to find entity set '{0}' in edm metadata".F(typeof(T).Name));
var tableName = GetStringProperty(entitySet, "Schema") + "." + GetStringProperty(entitySet, "Table");
return tableName;
}
private string GetStringProperty(MetadataItem entitySet, string propertyName)
{
MetadataProperty property;
if (entitySet == null)
throw new ArgumentNullException("entitySet");
if (entitySet.MetadataProperties.TryGetValue(propertyName, false, out property))
{
string str = null;
if (((property != null) &&
(property.Value != null)) &&
(((str = property.Value as string) != null) &&
!string.IsNullOrEmpty(str)))
{
return str;
}
}
return string.Empty;
}
This returns the actual name used in the database and well as the db schema (in case you're not using dbo), and should work with data annotations or fluent configuration.
The only caveat may be that the database should already be initialized. (which I think is the problem with using CreateObjectSet() - there's a step missing which resolves the db schema).
Using EF Core
protected virtual string GetTableName()
{
var entityType = dbContext.Model.FindEntityType(typeof(TEntity));
//Note: We need Nuget package Microsoft.EntityFrameworkCore.SqlServer
//var tableName = entityType!.GetSchemaQualifiedTableName();
var tableName = entityType!.GetTableName();
return tableName!;
}
Using EF6
using System.Data.Entity;
using System.Data.Entity.Infrastructure.DependencyResolution;
using System.Data.Entity.Infrastructure.Pluralization;
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Types().Configure(c => c.ToTable(GetTableName(c.ClrType)));
base.OnModelCreating(modelBuilder);
}
private string GetTableName(Type type)
{
var pluralizationService = DbConfiguration.DependencyResolver.GetService<IPluralizationService>();
var result = pluralizationService.Pluralize(type.Name);
result = Regex.Replace(result, ".[A-Z]", m => m.Value[0] + "_" + m.Value[1]);
return result.ToLower();
}
You can apply extension method to get Table name from your entity class
In this case, You wont need DbContext
to get table name , it gets it inside extension method
public static string GetTableName<T>(this T entity) where T : class
{
var object_context = GetObjectContext(entity);
if (object_context == null || object_context.TransactionHandler == null)
return null;
var dbcontext=object_context.TransactionHandler.DbContext;
var query= dbcontext.Set(entity.GetType()).ToString();
var reg = new Regex(@"FROM \[dbo\]\.\[(?<table>.*)\] AS");
var match = reg.Match(query);
var tableName= match.Groups["table"].Value;
return tableName;
}
private static ObjectContext GetObjectContext(object entity)
{
var field = entity.GetType().GetField("_entityWrapper");
if (field == null)
return null;
var val= field.GetValue(entity);
var property = val.GetType().GetProperty("Context");
var context = (ObjectContext)property.GetValue(val, null);
return context;
}
This is where we reach to DbContext
:
var object_context = GetObjectContext(entity)
Usage:
var tableName = entity.GetTableName();