Entity Framework Auto Migration - asp.net-mvc

Hi I am learning to develop project using code first approach. I am facing a small problem that when i run the command Add-Migration its not identifying the changes even i have enables the AutomaticMigrationsEnabled in config file
here is my code
----------------------------- DbContext file
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EntityCodeFirstSample.DataBaseFiles
{
class EntityCodeFirstSampleContext : DbContext
{
public EntityCodeFirstSampleContext()
: base("name=DbConnectionString")
{
Database.SetInitializer(new MigrateDatabaseToLatestVersion<EntityCodeFirstSampleContext, EntityCodeFirstSample.Migrations.Configuration>("DbConnectionString"));
}
public DbSet<Publisher> Publishers { get; set; }
public DbSet<Book> Books { get; set; }
public DbSet<Sample> Samples { get; set; }
public DbSet<Venkat> Venkats { get; set; }
}
}
----------------- Configurations file ---------------------------------
namespace EntityCodeFirstSample.Migrations
{
internal sealed class Configuration : DbMigrationsConfiguration<EntityCodeFirstSample.DataBaseFiles.EntityCodeFirstSampleContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = true;
AutomaticMigrationDataLossAllowed = true;
}
protected override void Seed(EntityCodeFirstSample.DataBaseFiles.EntityCodeFirstSampleContext context)
{
}
}
}
------------------------------------------- Model File ---------------------
namespace EntityCodeFirstSample.DataBaseFiles
{
[Table("Venkat")]
public class Venkat
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
public int NotaryCode { get; set; }
}
}
After running the command Add-Migration VenkatClass it is generating the migration file as below
namespace EntityCodeFirstSample.Migrations
{
using System;
using System.Data.Entity.Migrations;
public partial class VenkatClass : DbMigration
{
public override void Up()
{
}
public override void Down()
{
}
}
}

when AutomaticMigrationsEnabled = true then you don't have to add Migration because when you will execute your program the EF will look after for any change on the fly and update your database. If you want to control then set the AutomaticMigrationsEnabled = false. Then you should be able to see the difference when Add-Migration is being called.
Please read: https://msdn.microsoft.com/en-us/data/jj554735.aspx
and then read this: https://msdn.microsoft.com/en-us/data/jj591621.aspx
Run:
update-database
Make sure that the project is set default where the connection string is stored.
If it does not return any error then it is all good to go. You should able to see that the update has already occured and your new changes must have reflect already.

Related

The dbo.ASPNetUser and the other tables like this don't appear in my Server Explorer

I am working in my MVC5 project and I have created a DbContext different to the ApplicationDbContext but it inherits from the same class. I have been developing some parts of my project but now I want to add all the authentication and authorization stuff. But the tables that ASP.NET creates automatically for this purpose don't show up in my Server Explorer although I can work with the sets named Users and Roles of my context. I have searched the reasons of this but I found nothing useful. I hope someone can answer my question and whether it is an important issue or not. I add the code of my DbContext class. Sorry for my English cause I know it is terrible.
namespace GestionPaladares.Models
{
using System;
using System.Data.Entity;
using System.Linq;
using System.Data.Entity.ModelConfiguration.Conventions;
using GestionPaladares.Models;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
public class PaladarContext : IdentityDbContext<ApplicationUser>
{
// Your context has been configured to use a 'CodeFirstDatabaseModel' connection string from your application's
// configuration file (App.config or Web.config). By default, this connection string targets the
// 'GestionPaladares.Models.CodeFirstDatabaseModel' database on your LocalDb instance.
//
// If you wish to target a different database and/or database provider, modify the 'CodeFirstDatabaseModel'
// connection string in the application configuration file.
public PaladarContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
// Add a DbSet for each entity type that you want to include in your model. For more information
// on configuring and using a Code First model, see http://go.microsoft.com/fwlink/?LinkId=390109.
public virtual DbSet<Product> Products { get; set; }
public virtual DbSet<FoodAndDrink> Foods { get; set; }
public virtual DbSet<SoldBill> SoldBills { get; set; }
public virtual DbSet<CostBill> CostBills { get; set; }
public virtual DbSet<Seller> Sellers { get; set; }
public virtual DbSet<Grocer> Grocers { get; set; }
public virtual DbSet<Owner> Owners { get; set; }
public virtual DbSet<Category> Categories { get; set; }
public virtual DbSet<Measure> Measures { get; set; }
public virtual DbSet<Edge> Edges { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
}
Add ApplicationUser in Dbcontext
public DbSet<ApplicationUser> ApplicationUser { get; set; }
For example,
namespace GestionPaladares.Models
{
using System;
using System.Data.Entity;
using System.Linq;
using System.Data.Entity.ModelConfiguration.Conventions;
using GestionPaladares.Models;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
public class PaladarContext : IdentityDbContext<ApplicationUser>
{
// Your context has been configured to use a 'CodeFirstDatabaseModel' connection string from your application's
// configuration file (App.config or Web.config). By default, this connection string targets the
// 'GestionPaladares.Models.CodeFirstDatabaseModel' database on your LocalDb instance.
//
// If you wish to target a different database and/or database provider, modify the 'CodeFirstDatabaseModel'
// connection string in the application configuration file.
public PaladarContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
// Add a DbSet for each entity type that you want to include in your model. For more information
// on configuring and using a Code First model, see http://go.microsoft.com/fwlink/?LinkId=390109.
public virtual DbSet<Product> Products { get; set; }
public virtual DbSet<FoodAndDrink> Foods { get; set; }
public virtual DbSet<SoldBill> SoldBills { get; set; }
public virtual DbSet<CostBill> CostBills { get; set; }
public virtual DbSet<Seller> Sellers { get; set; }
public virtual DbSet<Grocer> Grocers { get; set; }
public virtual DbSet<Owner> Owners { get; set; }
public virtual DbSet<Category> Categories { get; set; }
public virtual DbSet<Measure> Measures { get; set; }
public virtual DbSet<Edge> Edges { get; set; }
public DbSet<ApplicationUser> ApplicationUser { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
}
Since you are using EF, you should first add migration, then do update database from the PM console window. Take a note you have to select the correct project form the list and be sure of the right connection string in your code or appsettings file.
Or, you have to create your own method to call on startup for fixing the database for you.
public static void EnsureDatabaseCreated(IConfiguration configuration)
{
using (var context = new DatabaseContext(configuration.GetConnectionString(GlobalConstants.APP_SETTINGS_CONNECTION_NAME)))
{
context.Database.Migrate();
}
}
public Startup(IConfiguration configuration, IHostingEnvironment environment)
{
EnsureDatabaseCreated(this.configuration);
}
Change the DatabaseContext class name with yours.
Hope this helps.

'System.Data.Entity.ModelConfiguration.ModelValidationException' occurred in EntityFramework.dll but was not handled in user code

I m working on an existing MVC project.When my context class inherited from DBContext everythink is fine but when i changed it to IdentityDbContext i get that error.The error occured in that line :
var makaleler = context.Makale.ToList();
my controller:
using mvcblogdeneme.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace mvcblogdeneme.Controllers
{
public class HomeController : Controller
{
// GET: Home
BlogDatabaseContext context = new BlogDatabaseContext();
public ActionResult Index()
{
return View();
}
public ActionResult CategoryWidgetGetir()
{
var kat = context.Kategori.ToList();
return View(kat);
}
public ActionResult TumMakalelerGetir()
{
var makaleler = context.Makale.ToList();
return View("MakaleListele", makaleler);//makalelistele bi partial view
}
}
}
this is my model:
namespace mvcblogdeneme.Models
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.Spatial;
[Table("Makale")]
public partial class Makale
{
public int Id { get; set; }
[Required]
[StringLength(150)]
public string Baslik { get; set; }
[Required]
public string Icerik { get; set; }
public DateTime YayimTarihi { get; set; }
public int KategoriID { get; set; }
public virtual Kategori Kategori { get; set; }
}
}
If the exception message shows like this and DbContext is being used:
EntityType '[[table name]]' has no key defined. Define the key for
this EntityType.
EntityType: EntitySet '[[entity name]]' is based on type '[[table name]]'
that has no keys defined.
Then definitely you need to use KeyAttribute on Id property to mark it as primary key field inside table model class and problem will solved:
[Table("Makale")]
public partial class Makale
{
// if the ID also set as auto-increment, uncomment DatabaseGenerated attribute given below
// [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Key]
public int Id { get; set; }
[Required]
[StringLength(150)]
public string Baslik { get; set; }
[Required]
public string Icerik { get; set; }
public DateTime YayimTarihi { get; set; }
public int KategoriID { get; set; }
public virtual Kategori Kategori { get; set; }
}
However, if the cause is found out coming from IdentityDbContext and EF Code First being used, you need to do these steps (credits to DotNetHaggis):
Create configuration class for IdentityUserLogin & IdentityUserRole:
// taken from /a/20912641
public class IdentityUserLoginConfiguration : EntityTypeConfiguration<IdentityUserLogin>
{
public IdentityUserLoginConfiguration()
{
HasKey(iul => iul.UserId);
}
}
public class IdentityUserRoleConfiguration : EntityTypeConfiguration<IdentityUserRole>
{
public IdentityUserRoleConfiguration()
{
HasKey(iur => iur.RoleId);
}
}
Add those two configurations above inside OnModelCreating method:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new IdentityUserLoginConfiguration());
modelBuilder.Configurations.Add(new IdentityUserRoleConfiguration());
}
At this point, the error should get resolved due to primary key for every identity tables has been set.
Similar issues:
An exception of type 'System.Data.Entity.ModelConfiguration.ModelValidationException' occurred in EntityFramework.dll
Merge MyDbContext with IdentityDbContext

If a class and its table are renamed how does the migration know to generate RenameTable?

I have a very simple context
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Common;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;
namespace WindowsFormsApplication1
{
[Table("MyParts2")]
public class MyPart2
{
[Browsable(false)]
[Key]
public int Id { get; set; }
}
public class EFProjectDbContext : DbContext
{
public EFProjectDbContext() // used for migrations
: base("name=ApplicationDatabase")
{
Database.SetInitializer(new CreateDatabaseIfNotExists<EFProjectDbContext>());
}
public EFProjectDbContext(string connectionString)
: base(connectionString)
{
if (Database.Exists())
{
// error here is benign uncheck break
var isCompatible = Database.CompatibleWithModel(false); //error occurs here
if (!isCompatible)
{
// uncheck break when this exception type is shown
// note if you are in debug you need to run exe to kick off upgrade
throw new Exception(
"The database is not compatible with the entity model. Drop the database or run migrations");
}
}
else
{
Database.SetInitializer(new CreateDatabaseIfNotExists<EFProjectDbContext>());
}
}
public EFProjectDbContext(DbConnection connection)
: base(connection, false)
{
}
public DbSet<MyPart2> MyParts2 { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
}
}
}
And i have migrations enabled
If I rename the class name and table attribute and create a migration the up method creates as
public override void Up()
{
RenameTable(name: "dbo.MyParts2", newName: "MyParts3");
}
How does it the create migration realise that the table is a rename and not a drop and re-create ?

Update-Database not updating identity tables

I am trying to update my database by using automatic migrations. I have recently added some properties to the Identity Model:
namespace CISC_Website.Models
{
public class ApplicationUser : IdentityUser
{
public string Email { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public bool ConfirmedEmail { get; set; }
}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("CISCDb")
{
}
}
}
However whenever I run the update-database command these changes are not pushed as my user tables are still the same as when they were first created.
Here is the contents of my migrations folder:
namespace CISC_Website.Migrations
{
using System;
using System.Data.Entity;
using System.Data.Entity.Migrations;
using System.Linq;
using System.Collections.Generic;
internal sealed class Configuration : DbMigrationsConfiguration<CISC_Website.Models.CISCDb>
{
public Configuration()
{
AutomaticMigrationsEnabled = true;
}
protected override void Seed(CISC_Website.Models.CISCDb context)
{
//seed data...
}
}
}
I know originally when the enable migrations command was run, the identity model was represented as such:
namespace CISC_Website.Models
{
public class ApplicationUser : IdentityUser
{
}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection")
{
}
}
}
Any idea how i can get these tables recognized??
Your application has two DbContexts: CISCDb and IdentityDbContext and you have configured migrations only for your CISCDb context. Therefore changes in the Identity context are not included in the CISCDb migrations.
You should be able to configure the migrations for the IdentityContext the same way you did for the other context to get it working.

ASP.Net MVC add controller error

When I try to add a 'MOVIES" controller, it errors: "There was an error generating 'MvcMovieSF.Models.MovieDBContext. Try rebuilding your project."
I have rebuilt the project and it continues to error. Thanks in advance!
namespace MvcMovieSF.Models
{
public class Movie
{
public int ID { get; set; }
public string Title { get; set; }
public DateTime ReleaseDate { get; set; }
public string Genre { get; set; }
public decimal Price { get; set; }
}
public class MovieDBContext : DbContext
{
public DbSet Movies { get; set; }
}
}
JUST NOTICED: I'm not sitting at my own computer and I noticed SQLExpress services were not started; I don't have permission on this computer to start the service. Could that be the reason?
Adding a controller also modifies your context class. If you have implemented partial class to add some business rules into your context, the framework cannot successfully edit your partial class to find the correct points for its own insertions.
Stupid, though, removing the business rules might help. After creating your controller, you can put them back.
(at least, this worked for me, 10 minutes ago...)
Edit:
The Context class might be partially implemented like this:
public partial class MyDatabaseEntities : DbContext
{
public override int SaveChanges() { ... }
#region Some Business Rules Here
...
#endregion
}
Here, if you try to add a new controller, you will fail with the error: "There was an error generating 'MyDatabaseEntities'. Try rebuilding your project."
And rebuilding will not help at all...
My solution is:
Remove these business rules like this, of course, keep them in a safe place, as you will probably need them afterwards:
public partial class MyDatabaseEntities : DbContext
{
public override int SaveChanges() { ... }
}
Create your controller. You should be successful this time.
Remove the codes that are added by the framework from your context class:
public partial class MyDatabaseEntities : DbContext
{
public override int SaveChanges() { ... }
public DbSet<MyModelClass> MyModelClass { get; set; } // remove this line
}
Put the business rules back.
Hope this helps.
I had the same problem while adding new controller in ASP.NET MVC 4, I solved the problem by moving the Database.SetInitializer(new SomeDataContextInitializer()); from the constructor of the DBContext to Application_Start method in Global.asax.cs. Hope it helps.
#Bolt Thunder put me on the right track. In my case, the DbContext class was modified to have IDbSet for testing, which made it happen. Changed that - problem solved.
my project name was MVC and i had this class
public class download
{
public int download_id { get; set; }
public int download_category_id { get; set; }
public string download_name { get; set; }
public int download_size { get; set; }
public string download_description { get; set; }
public string download_path { get; set; }
public download_category download_category { get; set; }
}
public class download_category
{
public int download_category_id { get; set; }
public string download_category_name { get; set; }
}
public class DownloadDbContext : DbContext
{
public DbSet<download> downloads { get; set; }
public DbSet<download_category> download_categorys { get; set; }
}
and i got similar error when scaffolding(there was an error generating try rebuilding your project).
i am using visual studio 2012 version 11.0.50727.1 RTMREL and reference to entity as ...\EntityFramework.5.0.0\lib\net45\EntityFramework.dll
first i divide class into three classes (three seperate *.cs files) and also use DataAnnotations in download and download_category classes to use [key] for id columns and problem solved.
my classes were as below in Models folder :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using MVC.Models;
using System.ComponentModel.DataAnnotations;
namespace MVC.Models
{
public class Download
{
[Key]
public int download_id { get; set; }
public int download_category_id { get; set; }
public string download_name { get; set; }
public int download_size { get; set; }
public string download_description { get; set; }
public string download_path { get; set; }
public Download_category download_category { get; set; }
}
}
and
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
namespace MVC.Models
{
public class Download_category
{
[Key]
public int download_category_id { get; set; }
public string download_category_name { get; set; }
}
}
and
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
namespace MVC.Models
{
public class DownloadDbContext:DbContext
{
public DbSet<Download> downloads { get; set; }
public DbSet<Download_category> download_categorys { get; set; }
}
}
I had the same problem as Susan. In my case specifying the model type for the DbSet (public DbSet<Movie> Movies ) in the context class fixed the problem.
I am using VS 2012 and i added the Entity Framework 5.0 package to the solution.

Resources