Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework | Code First - Get Name Of Created Table

Is it possible? I know I can get the name, when I've specified the TableAttribute, but it should be possible even so, when I let the framework manage the name.

Thanks in advance.

like image 278
0xbadf00d Avatar asked May 10 '11 11:05

0xbadf00d


People also ask

How do I use code first in Entity Framework?

Step 1 − First, create the console application from File → New → Project… Step 2 − Select Windows from the left pane and Console Application from the template pane. Step 3 − Enter EFCodeFirstDemo as the name and select OK. Step 4 − Right-click on your project in the solution explorer and select Manage NuGet Packages…

How do you use code first when an existing database schema?

To use code-first for an existing database, right click on your project in Visual Studio -> Add -> New Item.. Select ADO.NET Entity Data Model in the Add New Item dialog box and specify the model name (this will be a context class name) and click on Add.


3 Answers

I ended up with this:

public static class DbContextExt
{
    public static string GetTableName<T>(this DbContext context) where T : class
    {
        var type = typeof(T);
        var entityName = (context as System.Data.Entity.Infrastructure.IObjectContextAdapter).ObjectContext.CreateObjectSet<T>().EntitySet.Name;
        var tableAttribute = type.GetCustomAttributes(false).OfType<System.ComponentModel.DataAnnotations.Schema.TableAttribute>().FirstOrDefault();

        return tableAttribute == null ? entityName : tableAttribute.Name;
    }
}

It's a hybrid of the two answers here: DBset tabel name.

like image 161
mittio Avatar answered Oct 28 '22 02:10

mittio


The proper way to do this is to use the GetTableName method from the following page: http://romiller.com/2014/04/08/ef6-1-mapping-between-types-tables/

This includes support for the meta tag and model builder .ToTable() changes. The examples on this page basically return the DbSet property name which is not necessarily the table name in the database.

For example if you had:

DbSet<Config> Settings { get; set; }

The code on this page would return "Settings" for a table name when the actual DB table name is "Configs". And you would have the same issues if you used:

modelBuilder.Entity<Config>().ToTable("UserSettings")

Using the code in the provided link alleviates all of these issues. Here it is written as an extension:

public static class DbContextExtensions
{
    public static string GetTableName<T>(this DbContext context) where T : class
    {
        var type = typeof(T);
        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) == type);

        // 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;
    }
}
like image 44
jmichas Avatar answered Oct 28 '22 02:10

jmichas


If you don't use TableAttribute or fluent api to define the table name, the name will be inferred from the name of DbSet property in the context. The only thing which can modify the name in such case is pluralization convention which is used by default.

So if you have:

public class Context : DbContext
{
    public DbSet<User> Users { get; set; }
}

The table should be named Users.

like image 21
Ladislav Mrnka Avatar answered Oct 28 '22 01:10

Ladislav Mrnka