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());
}
}
Related
I am trying to create a ModelBuilder within my API and can't seem to add .HasRequired() to my code. I am assuming this is due to the fact that it lives within DBModelBuilder, however, I cannot add that also.
It will only allow me to use ModelBuilder.
Otherwise it throws an error: OnModelCreating(DbModelBuilder): no suitable method found to override
Am I missing something here?
My DbContext looks like so:
public class TicketContext : DbContext
{
public DbSet<Tickets> Tickets { get; set; }
public DbSet<Users> Users { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder) // <-- Not allowing me to add DbModelBuilder here
{
modelBuilder.Entity<Tickets>().HasRequired(t => t.Users);
}
}
Update
I have (as a test) started a new project from scratch. I created a new ASP.NET 5.0 project using a Web API template. Straight away my project doesn't recognize DbModelBuilder. I added reference to EntityFramework.dll and still no good. I then added using System.Data.Entity; and it then accepted DbModelBuilder but still complains that the namespace 'DbModelBuilder' could not be found.
I can't understand how I can have this error upfront on a brand new project?
As soon as I try and add the package Entity Framework from NuGet, I get more errors that version 6.1.3 is not compatible with DNX Core 5.0
I can't seem to find any examples/solutions to any of these errors.
Update 2
I have managed to get DbModelBuilder recognized now by adding the EntityFramework.dll reference to the DNX Core 5.0 Assembly as well as the DNX 4.5.1 assembly, however, now it has thrown even more errors wanting System.Core added and mscorlib. I really can't believe how much trouble it is to create a (what I thought would be simple) Web API project.
You can't just call HasRequired off the model builder - you need to indicate the entity you want to change:
public class MyContext: DbContext
{
public DbSet<Foo> Foos { get; set; }
public DbSet<Bar> Bars { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Foo>().HasRequired(f => f.Bar); // assumes Bar navigation added to Foo
}
}
https://msdn.microsoft.com/en-us/data/jj591617.aspx?f=255&MSPPError=-2147217396
What I like to do is separate out my fluent code like this:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new FooConfig());
}
Now I can create a class with all my mapping for that entity:
public class FooConfig : EntityTypeConfiguration<Foo>
{
public FooConfig()
{
// Primary Key
this.HasKey(t => t.FooId);
// Relationships
this.HasRequired(f => f.Bar).WithMany(b => b.Foos);
}
}
For some reason code-first EF7 (vNext) will not use/find the plural form of my table. I have tried adding the table attribute to the model but it does not solve the problem.
[Table("Units")]
public class Unit
If I name the table Unit then no problem. If I name the table Units then it's not found.
What am I doing wrong or missing?
Thank you.
This is how I resolved:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Unit>().ToTable("Units");
}
For Entity Framework 7 beta1, I solved this issue by this way:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Unit>().ForRelational(rb =>
{
rb.Table("Units");
});
}
Entity Framework 7 is being configured using the Fluent API. I created an extension method which maps the table names to their plural form, with the intention to reproduce the EF 6 behavior and to be able to use my existing database while working with EF7.
public static class ModelBuilderExtensions
{
public static void PluralizeNames(this ModelBuilder modelBuilder)
{
var types = modelBuilder.Model.EntityTypes;
foreach (var type in types.Where(type => type.ClrType != null))
{
modelBuilder.Entity(type.ClrType)
.ForRelational()
.Table(type.ClrType.Name.Split('`')[0].Pluralize());
};
}
}
Please note the .Pluralize() extension method. This may be Humanizer you're using or any other extension method which pluralizes your string. (I shamelessly copied https://github.com/srkirkland/Inflector/blob/master/Inflector/Inflector.cs in my project to be able to compile my project with the DNX Core.)
The .Split() part is to deal with the type.ClrType.Name which can output stuff like IdentityUserRole`1.
You can use it like this in your DbContext:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.PluralizeNames();
}
Ps; this works for me
Now the ToTable and ForRelational both are missing in beta5 of EF7. So I used the below code.
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<Role>().ForSqlServer().Table("Role");
}
You need to add "Microsoft.EntityFrameworkCore.Relational" in your project.json and restore your package.
.NET core is broken down in to small pieces for less memory foot print. So you need to explicitly tell what you want.
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);
}
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");
}
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;