Rename Navigation Properties while keeping data intact in Entity Framework - entity-framework

Have an Order table with several foreign keys to a User table (different types of users).
The Order entity has multiple properties that represent the keys over to the User table.
The problem is these navigation properties get named User1, User2, User3 etc...
Is there a way to update the names of these properties and keep them intact when updating the datamodel?
For example, some times during development, if I make a change to this table, I will some times delete the table from the model, update and rebuild etc.
I think I will just have to manually rename these properties and remember to do this if I update the table and datamodel, or is there another way?

using db-migration feature helps you to do that. advantage is that it helps you to have an archive of changes you have made during development. for each change you have a class that represent changes happened to database.
after enabling the migration for your project :
first turn off automatic update
public Configuration()
{
AutomaticMigrationsEnabled = false;
}
then use the code-first migration to generate migration class. write this in package manager :
add-migration renameColumns
then edit the created class to replace add/drop with rename.
public override void Up()
{
RenameColumn("Orders", "OldColumn", "NewColumn");
finally run update command in package manager to effect database
Update-Database

Related

Creating model for existing AspNetUsers table in Entity Framework Code First Approach

I am developing an Asp.Net mvc5 project. I am using Entity Framework code first approach to interact with the database. I am using Identity System for user authentication. But I am having a problem with integrating the AspNetUsers table from identity system to my model. My identity system database context and model database context class are different because I am using built in included identity system.
But connection string are same. Both use default connection string. But model is in different project. Now I am in the middle of the project. I have existing model classes mapped with tables in database. I created an user account from UI, so required tables(AspNetUsers table included) for identity system are auto-migrated. Now I want to create model class to map AspNetUsers table because I want to create relationship with between that AspNetUsers table and one of the existing tables. So I created a model class named "AspNetUser" class in my model project. Then I created properties for that class according to AspNetUsers table in database. Then I add migration and update database for my model. It gave me following error.
There is already an object named 'AspNetUsers' in the database.
What I can think is to delete AspNetUsers table and update database. But if I delete it, I have to delete other tables required for identity system because they have FK relationship. I do not want it. Second way I can think is to delete all required tables for identity system. Then migrate AspNetUser model class. Then delete that class and register new account from UI. So all required tables for identity system will be created again.
Second way also, I have to delete tables and happen data loss. How can I migrate overriding the existing AspNetUsers table? Is it possible? What is the best way to integrate AspNetUsers table to my model?
This is Configuration class in Migration folder
internal sealed class Configuration : DbMigrationsConfiguration<PatheinFashionStore.Domain.Concrete.StoreContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = true;
AutomaticMigrationDataLossAllowed = true;
}
protected override void Seed(PatheinFashionStore.Domain.Concrete.StoreContext context)
{
}
}
This is my context initializer class
public class ContextInitializer : System.Data.Entity.CreateDatabaseIfNotExists<StoreContext>
{
protected override void Seed(StoreContext context)
{
}
}
If it is not possible, what would be the best way?

Is it safe to modify an entity framework migration so that instead of dropping and recreating an index, it does it a different way?

Azure doesn't support "heap" tables, so I cannot "drop" the main index.
EntityFramework generates a migration that needs to drop and then recreate an index. Is it safe, before running the migration, to modify it so that instead of dropping and recreating the index, it copies the data to a new table with the new index, deletes the old table, then renames the new table to the old table's name?
The final state of the database, in the end, would be the same, so I think it's a safe change to make.
The model snapshot, etc. should all be the same.
We modify migrations regularly to create an additional index or to create a view instead of a table.
public override void Up() {
Sql(#"CREATE VIEW ... ");
}
public override void Down() {
Sql(#"DROP VIEW ... ");
}
As long as the final state of the database is compatible with you model, it is safe. You should only be careful about the "Down" part of the migration. If there is any chance you will ever run it, you should modify not only the Up method but also the Down method in your migration.

Entity Framework setting FK to nullable

I'm using code first with migrations to build and keep changes to the db in sync.
If there is a class Person that has a property that points to a class FavoriteColor the db schema that gets created is a Person table with a FK called FavoriteColor_Id which is non-nullable.
I need to have that column allow nulls since Person may or may not have a favorite color.
Thx
Ok once again with a good nights sleep I came in to work fresh and was able to tackle this in minutes.
Basically what had happened is that I was expecting that I would change my model class and a nice new migration cs file would be generated for me. There was no change to make to the model class since EF had auto generated this FK for me originally. I then realized that I could still run add-migration from the package manager console and it would create a new file for me where I could add my own code. I also needed to understand the difference between the Up() and Down() method. Sometimes you take these things for granted when everything is auto generated for you.
Here is what solved my issue:
public override void Up()
{
AlterColumn("dbo.Person", "FavoriteColor_Id", c => c.Int(nullable: true));
}

EF code-first migration: SqlCeException altering NTEXT column

My application uses Entity Framework 5.0 code-first on top of a Sql CE database. Until now, we have used Automatic Migrations to manage entity mapping changes. However, I now have a change for which I need to create a custom migration to ensure no data is lost during the update. I made my changes to the entities, and used the Add-Migration command which generated Up() and Down() methods for me. I customized the Up() method to insert my custom sql to preserve the data, and tested my application.
When I run the application, I received the error:
Unable to update database to match the current model because there are pending changes and automatic migration is disabled. Either write the pending model changes to a code-based migration or enable automatic migration. Set DbMigrationsConfiguration.AutomaticMigrationsEnabled to true to enable automatic migration.
Ok, I don't understand this because all of my changes are detailed in the Up() method that got executed.
So I turn Automatic Migrations back on just to see what happens. Now I receive this error:
"Cannot alter column of type NTEXT or IMAGE [ Column Name = LastName ]"
This error comes from a table/entity that hasn't even been touched with my changes. The existing database has this string mapped to nvarchar(4000). If I examine the DB after I receive this exception, I observe that the columns have been changed to ntext. What is EF doing? Why is it touching tables that haven't been changed? How can I get more information on what is going on here?
Update:
As a workaround, I attempted to mark each and every string type in my entities with a data annotation as such:
[Column(TypeName = "ntext")]
public virtual string LastName
{
get;
set;
}
Now all of my strings are using ntext in the database. This leads to further exceptions when queries are performed:
The ntext and image data types cannot be used in WHERE, HAVING, GROUP BY, ON, or IN clauses, except when these data types are used with the LIKE or IS NULL predicates.
So, to summarize:
Turning off automatic migrations causes EF to detect phantom changes and throw exceptions
Turning on automatic migration in conjunction with a custom migration causes all existing strings to be mapped to ntext
strings mapped to ntext cannot be queried, effectively making them useless in my application
For me, a modification of an Up method worked out.
SerialNumber = c.String(maxLength: 99)
was applied instead of
SerialNumber = c.String()
i had the same issue and i fixed by editing the table column data type manually by opening SQl Server Compact/SQlite Toolbox explorer windows, and then expend the database name, then expend the table you want to edit and right click the column you want to edit, and click drop script, then run the scrip and the column will be dropped from the table, then right click the table and click add column and from here you can choose what data type you want and add the new column that way. I hope this helps some one.

Entity Framework 6 Code First Migration's ContextKey

Now i'm using EF6 Alpha, and when using migration, it will add a new migration log into the __MigrationHistory table.
In EF6, The __MigrationHistory table has a new column called "ContextKey". After testing, I found there are two default "ContextKey" value:
The full name of DbContext's derived class.This happens when i run the code:
Database.CreateIfNotExists();
The full name of DbMigrationsConfiguration's derived class. This happens when i run the code:
public ArticleDbContext()
{
Database.SetInitializer(new MigrateDatabaseToLatestVersion<ArticleDbContext, ArticleConfiguration>());
}
The first time i run the application, "Database.CreateIfNotExists();" create a new database for me, also all tables that map to the models defined in ArticleDbContext, and then add a __MigrationHistory row which ContextKey's value is "Module.Article.Model.ArticleDbContext".
And then "Database.SetInitializer(new MigrateDatabaseToLatestVersion());" will be runned, this code will generate a new ContextKey "PowerEasy.Module.Article.Migrations.ArticleConfiguration". Migration query the __MigrationHistory table with this ContextKey and find out there's no data. So again it will create all tables that map to the models defined in ArticleDbContext, but the tables are already exist in the database, so an exception will be throwed, and tell me "the table XXX is already existed".
How can i solve this?
You should not mix Migrations and the Database.CreateIfNotExists method (or any of the initializers built on top of it). Migrations will take care of creating the database if it does not already exist.
As an alternative to the Migrations initializer, you can also apply migrations using the DbMigrator.Update method. This is useful if you want to create/update the database before it would otherwise be triggered by the initializer.