I use EF6 and MVC5
I use code-first for my project. and this is my DbContext:
public class ProjectServiceDBContext:DbContext
{
public ProjectServiceIranDBContext()
: base("ProjectServiceDBContext")
{ }
public DbSet<Service> Services { get; set; }
public DbSet<FormPost> FormPosts { get; set; }
public DbSet<Factory> Factories { get; set; }
public DbSet<PictureGallery> PictureGallery { get; set; }
public DbSet<Blog> Blog { get; set; }
public DbSet<Comment> Comment { get; set; }
public DbSet<User> Users { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new ServiceMapping());
modelBuilder.Configurations.Add(new FactoryMapping());
modelBuilder.Configurations.Add(new FormPostMapping());
modelBuilder.Configurations.Add(new PictureGalleryMapping());
modelBuilder.Configurations.Add(new BlogMapping());
modelBuilder.Configurations.Add(new CommentMapping());
modelBuilder.Configurations.Add(new UserMapping());
}
}
everything was fine before I Added new field to my Blog Model.
I use migrations to update my database . but its works just for one debug , if I stop debugging and start debugging again I get this error for updating database:
The model backing the 'ProjectServiceDBContext' context has changed since the database was created. Consider using Code First Migrations to update the database (http://go.microsoft.com/fwlink/?LinkId=238269).
I should use add-migration and update-database every time before debugging
what should I do?
I also delete Migration folder in my solution , and delete my tables in Database and try again and it's not works. also I create new DbContext but still this error is exist.
Try putting this in the constructor for your DbContext:
Database.SetInitializer<ProjectServiceDBContext>(null);
By default, Entity Framework Code-First uses the CreateDatabaseIfNotExists initializer. I think that's what is causing your problem..
If you change you code-first db models, the database needs to be updated to reflect that change. That is when you need to add a new migration and then apply it to ALL databases the application uses.
To apply to a production db, you might want to generate an SQL script of the changes using update-database -script.
Doesn't answer why your context is continually out of date but you could consider using AutomaticMigrations whilst in development.
See section Enabling Migrations
Related
I have a project that I'm moving from .NET 4.5 to .NET Core, for some reason (that I can't remember), I wanted to prevent pluralization of the table names when I ran an update-database like so (.NET 4.5):
public class UncoveredLink : DbContext
{
//removed constructor for brevity
public DbSet<Album> Albums { get; set; }
public DbSet<Artist> Artists { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//the line I'm talking about is here
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
So, when I look at my database in SQL Management Studio I see the following:
//what I see
dbo.Album
dbo.Artist
//what i want
dbo.Albums
dbo.Artists
I believe the lack of pluralization is what is causing this error when I try and load a page:
SqlException: Invalid object name 'Albums'.
//further down the stack trace i see
UnLink.Services.AlbumService.GetAlbumByStringExt(string stringExt) in AlbumService.cs
album = _db.Albums.Where(x => x.StringExt == stringExt).FirstOrDefault();
See? I'm trying to call _db.Albums but I believe I can't do this because the table is not pluralized and my Core Context doesn't have a pluralization OnModelCreating like my .NET 4.5 did (can't seem to add it).
My new DbContext in .NET Core 2.2 looks like this:
public class ApplicationDbContext : IdentityDbContext
{
public DbSet<Album> Albums { get; set; }
public DbSet<Artist> Artists { get; set; }
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
}
How can I update the table names? The tables in my Core DbContext (as seen above) are already pluralized so I can't make a change to the DbContext that would be tracked for a new add-migration... do I just manually create a migration file and update the table names like:
migrationBuilder.RenameTable(name: "Artist", schema: "dbo", newName: "Artists", newSchema: "dbo");
I thought it wasn't good practice to create a migration for something that wasn't actually changed/tracked in the code?
I think it can be helpful:
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
modelBuilder.Entity<Album>()
.ToTable("Album");
}
another way is:
[Table("Album")]
public class Album
{
public int AlbumId { get; set; }
public string Name { get; set; }
}
Well, you have made a change in the code, because you used to have that line about Remove<Pluralizing>, but now you don't. Unfortunately, Add-Migration might not pick up this change, especially when you're converting to .Net Core at the same time.
Since your model doesn't match your tables, you have the following options:
Manually create a migration that changes the table names:
migrationBuilder.RenameTable("Album", newName: "Albums");
OR
2. Write a query directly to the Db in SQL to change the table names:
EXEC sp_rename 'dbo.Album', 'dbo.Albums';
EF Core 2.0 introduces a new IPluralizer service that is used to singularize entity type names and pluralize DbSet names.
Maybe you could look into that. Plenty of posts about this on here or here's a blog post about that
I have simple context with 3 tables.
database tables are already present but using code first approach.
Model Device.cs is -
public class Device
{
public System.Guid Id { get; set; }
public string Name{ get; set; }
}
public class sampledbContext : DbContext
{
public sampledbContext ()
: base("name=sampledbContext ")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
public virtual DbSet<Device> Devices { get; set; }
}
To avoid extra s I have added above line into OnModelCreating but it is giving an error -
System.InvalidOperationException: 'The model backing the 'sampledbContext' context has changed since the database was created. Consider using Code First Migrations to update the database (http://go.microsoft.com/fwlink/?LinkId=238269).'
Database was already created and I try to use code first approach here.
I have not done update-database yet.
I tried doing Enable-Migration and Update-database it creates table with name s like Devices why ? s is added ?
You've turned off auto-migrations in the line:
Database.SetInitializer<IoTSimulatordbContext>(null);
And therefore you will need to run update-database manually to update the model (you can run this via package manager console). If you have any data in your tables it is likely that the migration will fail due to the possibility of losing data, in that case you will need to either delete all data from the tables first or make a custom migration script to handle copying the data first. As this seems like a test it may be better to restart the migration project with the pluralisation off from the beginning.
You can add a DataAnnotation to describe the Schema and Table name to your Table class such as this;
[Table("Device", Schema = "MySchema")]
This will give you more control over the naming.
I'm learning about Entity Framework and I want to create a project with it. I've use FluentNhibernate in my project but now I want to try Entity, but I have a doubt about how to create all tables(DBSet) when the application is loading. In my case I have 3 tables: Cliente, Produto, Venda, that I want to create when application is loading but I don't know how to do this.
How could I do this ?
trying
[DbConfigurationType(typeof(MySql.Data.Entity.MySqlEFConfiguration))]
public class DatabaseContext : DbContext{
public DatabaseContext():base("default"){
Database.SetInitializer<DatabaseContext>(new CreateDatabaseIfNotExists<DatabaseContext>());
//Database.CreateIfNotExists();
}
public DbSet<Cliente> clientes { get; set; }
public DbSet<Produto> produtos { get; set; }
public DbSet<Venda> vendas { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder){
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Entity<Produto>()
.Property(p => p.valor)
.HasPrecision(9,2); // or whatever your schema specifies
Database.SetInitializer<DatabaseContext>(null);
base.OnModelCreating(modelBuilder);
}
}
Assuming you already have all your DbContext and Entities setup and you are just asking about generating/updating the database, you are looking for Entity Framework's migration features.
Open Package Manager Console and run the following commands in your project:
// Enable migrations to your project
Enable-Migrations
// Add migrations to your project
Add-Migration
// Update any changes to the generated database
Update-Database
More details here:
https://martinnormark.com/entity-framework-migrations-cheat-sheet/
In the OnModelCreating method remove:
Database.SetInitializer<DatabaseContext>(null);
i suggest you to read:
http://www.entityframeworktutorial.net/code-first/database-initialization-strategy-in-code-first.aspx
and about automatic migration:
http://www.entityframeworktutorial.net/code-first/automated-migration-in-code-first.aspx
I have a site. using COde first. My add-migration command producted following code.
public partial class StudentEntity : DbMigration
{
public override void Up()
{
CreateTable(
"dbo.Student",
c => new
{
id = c.Int( nullable: false, identity: true),
name = c.String(),
})
.PrimaryKey(t => t.id);
}
Now I want to deploy my site so when site runs the first time I want the Student table to get generated in DB(SQL server).
Right now when I run the site it does not create any table. How can I do this? I dont want any seed data to initialize with
My db context class
public partial class flagen:DbContext
{
public flagen() : base("name=cf2")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
//old entity
public virtual DbSet<flag> flags { get; set; }
//new entity
public virtual DbSet<Student> students { get; set; }
}
Then I tried to use Context so table get created. It throws error "The model backing the 'flagen' context has changed since the database was created. Consider using Code First Migrations to update the database "
The I added following two lines to dbcontext class
Database.SetInitializer<flagen>(null);
base.OnModelCreating(modelBuilder);
now it says "invalid object name students"
any solution that works?
One solution could be to define a Initializer that will migrate your database to last existing migration you added. Therefore all tables will be created and the Seed method of the Configuration will be executed too - you could use it for seeding data.
With the following example your database will be updated to last existing migration (and therefore creates all tables) on first initialization of the data context. (var dbContext = new MyDatabaseContext())
In my opinion a much cleaner way than to use AutomaticMigrationsEnabled = true that you could check out too. ;)
As mentioned here is an example that will use the MigrateDatabaseToLatestVersion initializer with the defined behavior.
public partial class MyDatabaseContext : DbContext
{
public virtual DbSet<Student> students { get; set; }
public MyDatabaseContext() : base("MyDatabaseContextConnectionString")
{
System.Data.Entity.Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyDatabaseContext, Migrations.Configuration>());
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// here we want to define the entities structure
}
}
You will find some more information about the initializer itself here (MSDN
- MigrateDatabaseToLatestVersion) and here (Entity Framework Tutorial - Code-First Tutorials - Automated Migration) is another example with some more background information and examples.
The answer of this question is to use T4 templates. After searching the web I got the answer that nobody could on SO. Shame...
https://archive.codeplex.com/?p=t4dacfx2tsql
I am trying to run the code first migration in entity framework 6.0. I have added 4 new entities in my entities modal. However when i run the "add-migration" command in VS 2013, the generated migration file contains the script of all entitles (just like the initial migration) in my modal, though they are already in linked database. Obviously when I rum "Update-Database" commends, it generates entity already exists error. My DBContext class looks like following:
public class BidstructDbContext : DbContext
{
public BidstructDbContext() : base(nameOrConnectionString: "Bidstruct")
{
this.Configuration.LazyLoadingEnabled = false;
}
public DbSet<User> Users { get; set; }
public DbSet<Role> Roles { get; set; }
public DbSet<Permission> Permissions { get; set; }
public DbSet<Company> Company { get; set; }
// New Added Table
public DbSet<Gadgets> Gadgets { get; set; }
public DbSet<Language> Language { get; set; }
public DbSet<LanguageKeys> TranslationKeys { get; set; }
public DbSet<Translations> Translations { get; set; }
static BidstructDbContext()
{
Database.SetInitializer(new DatabaseInitializer());
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
}
}
and DatabaseInitializer class looks like as following:
public class DatabaseInitializer :
// CreateDatabaseIfNotExists<BidstructDbContext> // when model is stable
DropCreateDatabaseIfModelChanges<BidstructDbContext> // when iterating
{
private const int AttendeeCount = 1000;
// EF is NOT a good way to add a lot of new records.
// Never has been really. Not built for that.
// People should (and do) switch to ADO and bulk insert for that kind of thing
// It's really for interactive apps with humans driving data creation, not machines
private const int AttendeesWithFavoritesCount = 4;
protected override void Seed(BidstructDbContext context)
{
}
}
Any idea, how to resolve this problem. Its was working fine for me few days back but now I am facing this problem :(
Check to see if your context keys have changed, in your migration history.
I'm working on a project that has been using automatic migrations, but the automatic migration was not occurring due to a lot of class changes. In trying to switch to non-automatic migration, Add-Migration was regenerating the entire schema.
So I tried putting the manual table changes into the Up() of the DbMigration, and this applied a migration and an entry into the __MigrationHistory table, but with a different context key (the namespace and class name of my configuration file.)
A quick test of renaming the previous (older) migration record's context key to be the same as the current one caused the migration up/down to generate correctly.
Even then...it may not be 100%. Most of my changes were correct, but it started out adding a table which already existed, then turned around and removed it.