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));
}
Related
I'm trying to move property Tenant (of Type Tenant) from subclass to base class. I'm using TPH strategy and since I already have column Tenant_Id I would expect no changes in the migration.
However Entity Framework generates such a migration:
DropForeignKey("dbo.JobDetailsBases", "Tenant_Id", "dbo.Tenants");
AddColumn("dbo.JobDetailsBases", "Tenant_Id1", c => c.Guid());
CreateIndex("dbo.JobDetailsBases", "Tenant_Id1");
AddForeignKey("dbo.JobDetailsBases", "Tenant_Id1", "dbo.Tenants", "Id");
How can I tell EF to utilize the same column? I don't want to have column Tenant_Id1 for obvious reasons..
Update: I was trying to do it in two steps.. First remove the property from the subclass, generate the migration and then add in the base class and generate another migrations. I was hoping that this will improve the situation - it didn't.
The problem is that the first migrations is generated empty - EF does not want to remove that field. I updated the migration to remove it, but it still stays somehow in the model. The result is that even if I add this back EF will generate it like that (still with Tenant_Id1):
AddColumn("dbo.JobDetailsBases", "Tenant_Id1", c => c.Guid());
CreateIndex("dbo.JobDetailsBases", "Tenant_Id1");
AddForeignKey("dbo.JobDetailsBases", "Tenant_Id1", "dbo.Tenants", "Id");
So now the question is: how can I alter the internal EF model to get rid of the original property which I already removed from the class?
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
I'm trying to add an EntityObject to my database by calling AddToLeistungGruppe.
LeistungGruppe in this case is my Table with Primary_Key LeistungGruppe_ID with Identity true and Identity increment 1 and seed 1.
I search a lot for this issue and alot of People got he same error.
They were told to simply set StoreGeneratedPattern to Identity and this would solve the Problem.
I tried it out and still got the same issue.
I'm new to the Entity Framework and have no idea about how to solve this Problem.
Somehow i think the model isn't updated probably because even if i Switch around These Settings I'm getting the same error over and over again.
Every help is appreciated.
You are trying to save an object to the database with an explicit ID set by you while the database is expecting to generate that value itself. That is the LeistungGruppe_ID property in your object is set to something other than 0 and it is not identified to the EF framework as an identity field. If you want the Id to be generated by the database as your post suggests, then the corresponding property in the Object should be decorated with the [Key] attribute.
If you are using the Fluent API then you should have something like this in your DBContext:
protected override void OnModelCreating(System.Data.Entity.ModelConfiguration.ModelBuilder modelBuilder)
{
modelBuilder.Entity<LeistungGruppe>().Property(x => x.LeistungGruppe_ID).StoreGeneratedPattern = StoreGeneratedPattern.Identity;
base.OnModelCreating(modelBuilder);
}
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.
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.