Entity Framework: Get mapped table name from an entity


Extension methods for ObjectContext and DbContent to get the mapped table name from an entity.

Table of contents

The problem

I am working on a set of extension methods to perform a bulk insert using Entity Framework, using internally the SqlBulkCopy object. One of the steps involved is to get the mapped table name from an entity. After some google searching, I found a post on StackOverflow that led me to the solution.

The solution

The trick is to use the method ObjectQuery.ToTraceString to generate a SQL Select statement for an entity, and then extract the table name from that statement.

Let’s assume that you have an entity named Album corresponding to a table named dbo.Albums.

// context is ObjectContext
string sql = context.CreateObjectSet<T>().ToTraceString();

...

The generated SQL for that entity can be something like this:

SELECT 
[Extent1].[AlbumId] AS [AlbumId], 
[Extent1].[GenreId] AS [GenreId], 
[Extent1].[ArtistId] AS [ArtistId], 
[Extent1].[Title] AS [Title], 
[Extent1].[Price] AS [Price], 
[Extent1].[AlbumArtUrl] AS [AlbumArtUrl]
FROM [dbo].[Albums] AS [Extent1] 

So, all we need to do is to parse the SELECT statement to get the table name. This is the approach used in the post above but it has some limitations – that code will work only for tables that are in the default SQL Server schema (dbo.{tableName}). I made some changes to that code and I’m extracting the full table name using regular expressions.

The extension methods

I have created one extension method for DbContext and other for 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 the code

Getting the mapped table name for an entity named Album, using a ObjectContext object:

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

Or using a DbContext object:

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

References

Technorati Tags: ,
About these ads

4 thoughts on “Entity Framework: Get mapped table name from an entity

  1. If you’re dealing with Entity Framework proxies, you need to change the assignment for entityType to

    metadata
    .GetItems(DataSpace.OSpace)
    .Single(e => objectItemCollection.GetClrType(e).IsAssignableFrom(type));

    because the Proxy type is not in the objectItemCollection (but is assignable to type in that collection).

  2. Hi Rui,
    Nice blog post. I have a rather very similar requirement with what necessitated this post and was hoping you could help a little bit. First off, (and this might be a silly oversight on my behalf) the DbContext version of the ContextExtension method says “System.Data.Objects.ObjectContext does not contain a definition for GetTableName()”. What am I missing. Secondly, is it at all possible for you to share the rest of your SQLBulkCopy implementation. Many thanks for this.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s