15

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?

Alexandre
  • 6,532
  • 5
  • 50
  • 70

7 Answers7

25

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:

Entity Framework: Get mapped table name from an entity

Rui Jarimba
  • 10,350
  • 10
  • 55
  • 79
  • I get "Cannot resolve symbol 'GetTableName'" on the line `return objectContext.GetTableName();` in the `DbContext` version. – ProfK Jun 08 '13 at 06:50
  • @ProfK: do you have the extension methods in the same class? – Rui Jarimba Jun 08 '13 at 10:58
  • No, they're in an extensions class like all my extensions. I can't make my DbContext class static. – ProfK Jun 08 '13 at 13:04
  • @ProfK: sorry but I don't understand what you're trying to say.... Why would you make your DbContext class static? – Rui Jarimba Jun 09 '13 at 10:46
  • I don't. I thought you meant did I have extension methods in the same class as my DbSet. My bad. – ProfK Jun 09 '13 at 15:16
8

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.

Avi Cherry
  • 3,867
  • 1
  • 25
  • 31
6

Try something like this:

string name = (context as IObjectContextAdapter).ObjectContext.CreateObjectSet<MyClass>().EntitySet.Name;
Devart
  • 115,199
  • 22
  • 161
  • 180
4

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

Jethro
  • 5,838
  • 2
  • 22
  • 23
1

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).

Tim Abell
  • 10,156
  • 8
  • 75
  • 104
Ackroydd
  • 1,377
  • 13
  • 13
0

Source: https://msdn.microsoft.com/en-gb/data/jj819164.aspx

using System.Data.Entity;
using System.Data.Entity.Infrastructure.DependencyResolution;
using System.Data.Entity.Infrastructure.Pluralization;

var service = DbConfiguration.DependencyResolver.GetService<IPluralizationService>();
var entitySetName = service.Pluralize(typeof(TEntity).Name));
hpsanampudi
  • 491
  • 4
  • 8
  • 2
    This doesn't use configuration, instead it only assumes default conventions. This doesn't work when overriding the table name manually, when not using the pluralization convention or when using a custom naming convention. – mycroes Dec 08 '20 at 09:31
0

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();
Abolfazl
  • 1,380
  • 10
  • 26