How to do manual table mapping in Entity Framework 5 using the Code First approach?
What I mean by table mapping is to associate a table name from the database to an entity class with a different name.
This is pretty simple.
[Table("Foo")]
public class Bar {
// properties
}
For fluent api:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<MyEntity>().ToTable("MyTargetTable");
}
Related
I have an ASP.NET Core application. I have structured the application as multiple projects under the solution. In two of the projects I have 2 different contexts for the same database. The problem is I have a table I am using for auditing in both contexts, and this is causing a problem with migration.
My question is:
is there anyway I can make migration ignore creating this table in one of the contexts?
I am getting the error in the following line:
dbContext.Database.Migrate();
in you dbContext you can ignore one or more table using model builder ignore and give the entity class type you want to ignore
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Ignore<YourClassHere>();
}
You can do this by adding onModelCreating method.
public class ApplicationDbContext : DbContext
{
public DbSet<TableName> TableNames { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<TableName>().ToTable(nameof(TableNames), t =>
t.ExcludeFromMigrations());
}
}
Is it possible to change table name "__MigrationsHistory" when using codefIrst?
Problem: I am using Oracle Database and I have rules to create new tables. One of them is that there can not be any table names or fields with special characters.
Refer this Link - Is changing the name of the EF __Migration History table dangerous?
This will explain on how to rename the database and what should be done.
This is a bit late but, could help someone who struggle having multiple DBContexts using the same DB scheme.
In order to rename __MigrationHistory table; create a custom class that implements HistoryContext class and override parents OnModelCreating method. Then create a custom configuration class, pass our custom HistoryContext with SetDefaultHistoryContext method.
Please take a look at System.Data.Entity.Migrations.History.HistoryContext
A custom HistoryContext class;
public class YourHistoryContext : HistoryContext
{
public YourHistoryContext(System.Data.Common.DbConnection dbConnection, string defaultSchema)
: base(dbConnection, defaultSchema)
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<HistoryRow>().ToTable(tableName: "YourCustomMigrationHistory"/*, schemaName: "dbo__OrYourCustomScheme"*/);
//Rename Id column name.
//modelBuilder.Entity<HistoryRow>().Property(p => p.MigrationId).HasColumnName("Migration_ID");
}
}
Create a custom DbConfiguration class;
public class MigrationHistoryConfiguration : DbConfiguration
{
public MigrationHistoryConfiguration()
{
//this.SetHistoryContext("System.Data.SqlClient",
// (connection, defaultSchema) => new HistoryContext(connection, defaultSchema));
this.SetDefaultHistoryContext((connection, defaultSchema) => new YourHistoryContext(connection, defaultSchema));
}
}
We are using a database created several years ago, and would like to keep the table names the same.
All of our tables are named like: "tbl_Orders" but we would like the class names for the models / controllers / etc. to be Orders / OrdersController / etc. We are mapping the classes to our tables using Entity Framework.
Sorry if this has been asked before, I tried searching but came up empty handed...
Solution:
After some back and forth with Scott Chamberlain, we came to the conclusion that both answers are correct. I went ahead and marked Masoud's answer as accepted, because that is the route I went. Thank's to everyone who helped (especially Scott).
You can use the Table attribute or the fluent api to map between table names in your database and class names
[Table("tbl_Blogs")]
public class Blog
3rd party edit
Entity framework core offers the same option to map tablenames or columns
map tables names
map column names
The mapping can be done by using attributes
[Table("blogs")]
public class Blog
{
[Column("blog_id")]
public int BlogId { get; set; }
public string Url { get; set; }
}
or by using the fluent api
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.ToTable("blogs");
modelBuilder.Entity<Blog>()
.Property(b => b.BlogId)
.HasColumnName("blog_id");
}
You can use following code in your DbContext to map all your entities to your tables:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// TableNameConvention
modelBuilder.Types()
.Configure(entity =>
entity.ToTable("tbl_" + entity.ClrType.Name));
base.OnModelCreating(modelBuilder);
}
Working on EF Core 7.0(5.0+) and this one worked for me.
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
foreach (var mutableEntityType in modelBuilder.Model.GetEntityTypes())
{
// check if current entity type is child of BaseModel
if (mutableEntityType.ClrType.IsAssignableTo(typeof(BaseEntity)))
{
mutableEntityType.SetTableName($"tbl_{mutableEntityType.ClrType.Name.Pluralize()}");
}
}
base.OnModelCreating(modelBuilder);
}
I am creating an Entity Framework Code-First model to execute ad-hoc queries against a SQL Server database. I am not including any tables/views from the "dbo" schema in my EF model; instead I am only including tables/views from the "model" schema in my database. I do have duplicate names of objects in my database that are separated only by schema (e.g. "dbo.Child" and "model.Child").
Is there one line I can specify in the DbContext that will say in essence "map all entities in this context to the 'model' schema"? I know that I can map each entity to the proper schema (see below), but I'd like to avoid listing out every entity in my database again.
This is what I know I can do:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Child>().ToTable("Child", "model");
modelBuilder.Entity<Referral>().ToTable("Referral", "model");
// 100 lines later...
modelBuilder.Entity<Exit>().ToTable("Exit", "model");
}
This is what I'd like to do:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Add(new MapAllEntitiesToSchemaConvention("model"));
}
I couldn't find anyway to do this out of the box in EF 4.2, but I needed all my entities to be in a different schema so I hacked this up in an attempt to keep things DRYer. It uses the same underlying pluralization engine as EF, and the overrides are there incase entities need to specify the table name.
A reference to System.Data.Entity.Design is needed.
public class BaseConfiguration<TEntityType> : EntityTypeConfiguration<TEntityType> where TEntityType : class
{
private readonly static PluralizationService ps = PluralizationService.CreateService(new CultureInfo("en-US"));
public BaseConfiguration() : this(ps.Pluralize(typeof(TEntityType).Name)) { }
public BaseConfiguration(string tableName) : this(tableName, MyContext.Schema) { }
public BaseConfiguration(string tableName, string schemaName)
{
ToTable(tableName, schemaName);
}
}
I define the schema name via a constant string in MyContext, ie:
public class MyContext : DbContext
{
public const string Schema = "my";
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new SnapshotConfiguration());
}
}
And my entities configurations look like:
public class SnapshotConfiguration : BaseConfiguration<Snapshot>
{
...
}
Caveat: I still need configuration's for each entity I want in the correct schema - but the jist of it could be adopted elsewhere.
I prefer using singular nouns when naming my database tables. In EF code first however, the generated tables always are plural. My DbSets are pluralized which I believe is where EF is generating the names but I don't want to singularize these names as I believe it is more pratical to have them plural in code. I also tried overriding the setting but to no avail.
Any ideas? Here is my code and thanks.
MyObjectContext.cs
public class MyObjectContext : DbContext, IDbContext
{
public MyObjectContext(string connString) : base(connString)
{
}
public DbSet<Product> Products {get;set;}
public DbSet<Category> Categories {get;set;}
//etc.
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingEntitySetNameConvention>();
}
}
You've removed the wrong convention (PluralizingEntitySetNameConvention) for this purpose. Just replace your OnModelCreating method with the below and you will be good to go.
using System.Data.Entity.ModelConfiguration.Conventions.Edm.Db;
...
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
With Entity Framework 6, on your file that inherit from DbContext:
using System.Data.Entity.ModelConfiguration.Conventions;
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
You can also change the property value:
On the Tools menu, click Options.
In the Options dialog box, expand Database Tools.
Click O/R Designer.
Set Pluralization of names to Enabled = False to set the O/R Designer so that it does not change class names.
Set Pluralization of names to Enabled = True to apply pluralization rules to the class names of objects added to the O/R Designer.
The location of the definition of PluralizingTableNameConvention has moved to:
using System.Data.Entity.ModelConfiguration.Conventions;