EFT CTP5 Disable Identity column on insert - entity-framework-ctp5

I have an existing database that I would like to migrate to EF CTP5. The problem I have is that when I insert the existing data I need it to move retaining the current identity primary key for the other foreign key constraints.
I would like to migrate this using EF CTP5 code so I dont have to write lots of SQL or even contain it within an SSIS Package.
I have attempted to use the sql syntax:
SET IDENTITY_INSERT tableName ON
SET IDENTITY_INSERT tableName OFF
However, when DbContext.SaveChanges() is called the above syntax is happening in a different connection and the identity column is controlled by the EF CTP5 framework, even when specifying the ID.
Is there a way of disabling, or removing the identity convention to an object similar to the following, but on the fly rather than when the database is instantiated:
public class BlogContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<StoreGeneratedIdentityKeyConvention>();
}
}
Thanks

You can add the Identity setting on a field like so:
In your OnModelCreating in your DbContext class:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<ClassNameOfYourPOCO>().Property(p => p.IDFIELDNAME)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
}
You can remove it like so:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<ClassNameOfYourPOCO>().Property(p => p.IDFIELDNAME)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
}

Related

ef core migration insert data

I'd like to insert data into table in migration. Is it possible? Migration needs parameterless constructor available and I'd like to use db context defined in Startup.cs file (best I'd like to get it throught dependency injection). How do that?
In the EF Core 2.1, migrations can automatically compute what insert, update or delete
operations must be applied when upgrading the database to a new version of the model.
As an example, we have a User and UserComment entities like these:
public class User
{
public int UserId { get; set; }
public string Name { get; set; }
public List<UserComment> UserComments { get; set; }
}
public class UserComment
{
[Key]
public int CommentId { get; set; }
public string CommentTitle { get; set; }
[ForeignKey("User")]
public int FKUserId { get; set; }
public User User { get; set; }
}
In the DBContext, override the OnModelCreating function and seed data to each entity:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<User>().HasData(new User[] {
new User{UserId=1,Name="iman"},
new User{UserId=2,Name="Alex"},
});
}
To seed datas that have a relationship, the foreign key value must be specified:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<UserComment>().HasData(new UserComment[] {
new UserComment{FKUserId=1,CommentId=1,CommentTitle="Comment1"},
});
}
Be careful: you must use migrations to apply changes
Migration is a process of "upgrading" your DB to a new "version". During this, your existing DB tables ("old version") does not required to match your classes (entities) ("new version"), so you can't safely use them.
During migration you should operate only with tables and records using raw SQL commands. You may use migrationBuilder.Sql("UPDATE ..."); for such updates, put them manually into migration Up() code.
If you need perform data modifications using entity classes - you should use "Seed Data" solution (from #itikhomi comment), but remember that it will be run every time your app starts, so you should do some version-check inside it.

Renamed default tables but AspNetusers Table Still Getting Created

I am working with ASP.NET identity. I renamed the default tables using the following code.
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<IdentityUser>().ToTable("Users");
modelBuilder.Entity<IdentityRole>().ToTable("Roles");
modelBuilder.Entity<IdentityUserRole>().ToTable("UserRoles");
modelBuilder.Entity<IdentityUserClaim>().ToTable("UserClaims");
modelBuilder.Entity<IdentityUserLogin>().ToTable("UserLogins");
}
}
}
But when I run my app, AspnetUsers is still created but with a single column named 'Id'. This table is being populated along with the new "Users" table. Why? And how do I stop this behavior.
I see the same question asked here, but without a good response: Identity 2.0 Code First Table Renaming
I hope I am not violating StackOverflow's guidelines in reasking this question/// if so apologies in advance!
Stumbled across this post when looking for a quick solution - now I've dug a bit through the code and found the answer; maybe it helps someone.
I suppose you have overwritten the default IdentityUser class, right?
public class ApplicationUser : IdentityUser
{
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
...
In that case, you'll have to exclude the default IdentityUser from the ModelBuilder:
protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
//modelBuilder.Entity<IdentityUser>().ToTable("Users", "dbo"); // we have overwritten IdentityUser, so no more need for the empty AspNetUsers table
modelBuilder.Entity<ApplicationUser>().ToTable("Users", "dbo"); // Use ApplicationUser instead
modelBuilder.Entity<IdentityRole>().ToTable("Roles", "dbo");

Auto-increment IDs after importing data in the Entity Framework

I'm developing a new version of an old application using Entity Framework 6 Code First and ASP.NET with SQL Server 2014 as the back end. The old database is an Access database and has about a dozen tables with auto-increment IDs. I want to import the old data while keeping the IDs intact so that the relationships between the tables is preserved. I've set the key attribute on the new entities to
DatabaseGeneratedOption.None
This works, and I'm able to import all of the values from the old database, however I'd like to have the primary keys auto-increment from this point on. Since the DatabaseGeneratedOption is set to None it seems that I have to manually generate IDs in
You probably want to set the keys as identity as they were and then disable the identity-constraint during import.
You do this with SET IDENTITY_INSERT tablename ON before the insert statement. Dont forget to set it to OFF when you are done.
I never tried this, but you can have different configurations and switch them as per requirement/environment, hope this helps
public class IdentityDbConfiguration : EntityTypeConfiguration<Foo>
{
public IdentityDbConfiguration()
{
Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
}
}
public class DbConfiguration : EntityTypeConfiguration<Foo>
{
public DbConfiguration()
{
Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
}
}
public class AppContext : DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new IdentityDbConfiguration());
}
}
public class AppContext2 : DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new DbConfiguration());
}
}

How can I avoid ASP.NET Identity from adding this extra field?

I have a new MVC5 project with ASP.NET Identity 2.0 and EF 6.1.1.
I added my own ApplicationUser (based on built-in IdentityUser). This is how my DbContext is created.
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
When the database is created I have tables like AspNetUsers, AspNetUserRoles, AspNetUserClaims, and AspNetUserLogins. Then I added OnModelCreating() with just the most basic statements.
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<IdentityUserLogin>().HasKey<string>(l => l.UserId);
modelBuilder.Entity<IdentityUserRole>().HasKey(r => new { r.RoleId, r.UserId });
}
As soon as I add OnModelCreating(), the identity tables are automatically renamed to ApplicationUsers, IdentityUserRoles, IdentityUserClaims, and IdentityUserLogins. That's fine with me (and I know how to rename them).
But what I don't like: All of a sudden, IdentityUserRoles, IdentityUserClaims, and IdentityUserLogins have an extra field called "ApplicationUser_Id". The original "AspNetXXX" tables didn't have such a field.
Why is that? And is there anything I can do in order to avoid this?
You need to call base.OnModelCreating. There are a number of additional things OnModelCreating does in IdentityDbContext that you may be missing without calling it - the default names of the tables being one of them.
Its best to call it first, then apply your own changes afterwards.
As mentioned by Matt Lassam-Jones
worked for me also and Thank You.
public class NebulaContext : IdentityDbContext<ApplicationUser>
{
public NebulaContext()
: base("Name=MyEntity", throwIfV1Schema: false)
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>(); //Optional
modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();//Optional
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>(); //Optional
base.OnModelCreating(modelBuilder);
}
}

Model change detection ASP.NET code first migrations

I have added
public IEnumerable<Comment> Comments { get; set; }
to a Model in an ASP.net MVC project. I ran the following to generate a migration in the package console
PM> Add-Migration AddCommentsToDevice
and the resulting migration did not pick up the change to the model
public partial class AddCommentsToDevice : DbMigration
{
public override void Up()
{
}
public override void Down()
{
}
}
Any tips on the syntax of the migrations or what causes detections?
You've added to little. You need to configure the relationship properly - the best with fluent api. Use this for navigation property:
public virtual ICollection<Comment> Comments { get; set; }
Important - always use ICollection, not IEnumerable for Navigation properties and make them virtual - thanks to this ef will be able to track changes.
Then in your DbContext you add following code:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Model>().HasKey(x => x.Id);
modelBuilder.Entity<Model>().HasMany(x => x.Comments);
base.OnModelCreating(modelBuilder);
}
I assumed that class related to Comments is named Model.

Resources