Entity Framework code-first migration: revert migration not working using down() method - entity-framework-6

I have successfully add new column in table using Add-Migration AddMobileNo using Entity Framework code-first approach.
[Table("Student")]
public class Student
{
[Key]
public int StudentId { get; set; }
public string Name { get; set; }
// Add new column using "Add-Migration AddMobileNo"
public string MobileNo { get; set; }
}
public partial class AddMobileNo : DbMigration
{
public override void Up()
{
AddColumn("dbo.Student", "MobileNo", c => c.String());
}
public override void Down()
{
DropColumn("dbo.Student", "MobileNo");
}
}
Now I am trying to revert a migration using this command for calling down() method:
update-database -TargetMigration: "AddMobileNo"
but it's not working for me and showing this message in PMC (Package Manager Console):
Target database is already at version AddMobileNo
Thanks in advance.

Related

Code migration unexpectedly tries to rename table

I want to implement a change log as advised in
Dev Express XAF T474899
I am using the security system generated by the XAF new solution wizard
I have defined some business objects to store the change log information.
One of these objects stores a link to the user
public virtual User User { get; set; }
On generating the code migration I am surprised to see the Up() method add the following
RenameTable(name: "dbo.UserRoles", newName: "RoleUsers");
DropPrimaryKey("dbo.RoleUsers");
AddPrimaryKey("dbo.RoleUsers", new[] { "Role_ID", "User_ID" });
On another occasion I found the following in an Up()
RenameTable(name: "dbo.EventResources", newName: "ResourceEvents");
// lots of other stuff
DropPrimaryKey("dbo.ResourceEvents");
AddPrimaryKey("dbo.ResourceEvents", new[] { "Resource_Key", "Event_ID" });
On both occasions the code that creates the entities is a Dev Express libary.
I have cross posted this question to Dev Express Support
The Dev Express business objects are defined in DevExpress.Persistent.BaseImpl.EF;
My DbContext context refers to them as
public DbSet<Role> Roles { get; set; }
public DbSet<User> Users { get; set; }
The meta data for Role shows
The meta data for User shows
My own business classes contain
namespace SBD.JobTalk.Module.BusinessObjects
{
[NavigationItem("Configuration")]
[DisplayName("Staff")]
[DefaultProperty("Summary")]
[ImageName("BO_Employee")]
[Table("Staff")]
public class Staff : BasicBo
{
public Staff()
{
Person = new Person();
}
public virtual Person Person { get; set; }
[StringLength(100, ErrorMessage = "The field cannot exceed 100 characters. ")]
[scds.Index("IX_Staff_UserName", 1, IsUnique = true)]
public string UserName { get; set; }
[NotMapped]
public string Summary => $"{Person.FirstName} {Person.LastName}";
//public virtual User User { get; set; }
}
}
public abstract class BasicBo : IXafEntityObject
{
[Browsable(false)]
[Key]
public virtual int Id { get; set; }
public virtual void OnCreated()
{
}
public virtual void OnSaving()
{
}
public virtual void OnLoaded()
{
}
}
If I un-comment the code to have the User property inside Staff, and generate a migration, the migration Up is
public override void Up()
{
RenameTable(name: "dbo.UserRoles", newName: "RoleUsers");
DropPrimaryKey("dbo.RoleUsers");
AddColumn("dbo.Staff", "User_ID", c => c.Int());
AddPrimaryKey("dbo.RoleUsers", new[] { "Role_ID", "User_ID" });
CreateIndex("dbo.Staff", "User_ID");
AddForeignKey("dbo.Staff", "User_ID", "dbo.Users", "ID");
}
[Update]
Interestingly there are more Dev Express tables than I first thought.
The primary keys are Identity.
I think am using Standard Authentication created before Dev Express added the Allow/Deny ability (V16.1)
[Update]
When I create a new project with the above settings, here is the DbContext.
using System;
using System.Data;
using System.Linq;
using System.Data.Entity;
using System.Data.Common;
using System.Data.Entity.Core.Objects;
using System.Data.Entity.Infrastructure;
using System.ComponentModel;
using DevExpress.ExpressApp.EF.Updating;
using DevExpress.Persistent.BaseImpl.EF;
using DevExpress.Persistent.BaseImpl.EF.PermissionPolicy;
namespace XafApplication1.Module.BusinessObjects {
public class XafApplication1DbContext : DbContext {
public XafApplication1DbContext(String connectionString)
: base(connectionString) {
}
public XafApplication1DbContext(DbConnection connection)
: base(connection, false) {
}
public XafApplication1DbContext()
: base("name=ConnectionString") {
}
public DbSet<ModuleInfo> ModulesInfo { get; set; }
public DbSet<PermissionPolicyRole> Roles { get; set; }
public DbSet<PermissionPolicyTypePermissionObject> TypePermissionObjects { get; set; }
public DbSet<PermissionPolicyUser> Users { get; set; }
public DbSet<ModelDifference> ModelDifferences { get; set; }
public DbSet<ModelDifferenceAspect> ModelDifferenceAspects { get; set; }
}
}
OK, I will take a stab :) Your Up() code is trying to rename the table UserRoles to RoleUsers. This means you have a prior migration where UserRoles was the table name - probably from your DevEx stuff. This could happen if they changed their models in an upgrade. The current models are expecting RoleUsers etc. so you need to get there.
So first option is let the migration do the renaming to match the underlying model. I assume this didn't work or causes other issues?
You might be able to 'fool' entity framework into using the old tables with fluent code or annotations, but if it has new columns or relationships that won't work.
What I would do is this:
1) Create a new test project with the same references you had and
copy your context and DbSets. Point the connection string to a
new database.
2) Add a migration and script it out:
update-database -Script.
3) Examine this script a use it to create
the objects needed in your database. Migrate data from the old
tables to new if needed.
4) Remove the old tables
5) In your actual
project add a migration to resync your models:
add-migration SyncDevExUpdate -IgnoreChange, update-database
Now you will have the tables your models expect.

Code first initial create with MVC identity 2.0

I'm creating initial migration using
Add-Migration InitialCreate
But then when I'm updating my database tables from IdentityDbContext are not created so I get exceptions.
So how do I create migration for AspNetUser tables from IdentityDbContext?
Regards teamol
You can add custom fields to your AspNetUser table in your IdentityModels.cs file.
First add your custom values ito ApplicationUser class in IdentityModels:
namespace YourProjectName.Models
{
public class ApplicationUser : IdentityUser
{
public string Email { get; set; }
public string NameSurname { get; set; }
public string ProfilePhotoRoute { get; set; }
public string Title { get; set; }
}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection")
{
}
}
After that, enter "Add-Migration NewMigration" command in package manager console.
Finally, enter "Update-Database" command in package manager console.
If your connection string -which is stated in web.config- is true, you can update succesfully your database with this way.

Table name in data annotations in entity framework doesn't work.

I create a project in MVC 5 with entity framework 6. I am using code first approach. I want in one of the models define a different name for the table then the default. For that I use the System.ComponentModel.DataAnnotationsname space and define the class like this:
[Table(Name="Auditoria")]
public class AuditoriaDAL
{
[Key]
public int AuditoriaId { get; set; }
...
}
Running the project I get a database with a table with the name AuditoriaDALs. Why the table have this name a not the name that I define?
You are referencing the System.Data.Linq.Mapping.Table attribute when you need to reference System.ComponentModel.DataAnnotations.Schema.Table. So either do this:
[System.ComponentModel.DataAnnotations.Schema.Table("Auditoria")]
public class AuditoriaDAL
{
[Key]
public int AuditoriaId { get; set; }
...
}
Or better yet:
using System.ComponentModel.DataAnnotations.Schema;
...
[Table("Auditoria")]
public class AuditoriaDAL
{
[Key]
public int AuditoriaId { get; set; }
...
}
https://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations(v=vs.110).aspx
you can set TableName like below :
public class MyContext : DBContext
{
public virtual DbSet<AuditoriaDAL> Auditorias { get; set; }
}
Or in OnModelCreating :
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<AuditoriaDAL>().ToTable("Auditorias");
}
The name= isn't necessary. You should try [Table("Auditoria")].

Entity Framework Auto Migration

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.

MVC migration is empty

I've added a simply Product-class (shown below) but when I run add-migration it generates an empty script. I guess this is hard to troubleshoot but any idea as to why this is?
public class Product
{
public int ProductID { get; set; }
[Required]
public string Name { get; set; }
[DataType(DataType.Currency)]
public decimal Price { get; set; }
}
public class ProductDBContext : DbContext
{
public DbSet<Product> Products { get; set; }
}
The migration file looks like this:
public partial class test : DbMigration
{
public override void Up()
{
}
public override void Down()
{
}
}
Have you added the according Class to your DB context?
public System.Data.Entity.DbSet YourDbSetName { get; set; }
Try Clearing out _MigrationHistory (and possible also opening your Project.Data.csproj to manually delete te migrations pending)
I found the answer here: solution

Resources