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.
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…
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.
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.
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;
}
}
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With