How to affect the column order with Entity Framework Code First Migrations - entity-framework

I'm using Entity Framework 4.3 Code First and trying out the Migrations feature.
If I add a new property to my class and then run Add-Migration from the package manager console window I get something like this:
public override void Up()
{
AddColumn("Products", "Discontinued", c => c.Boolean(nullable: false));
}
I would like to be able to affect the order of the column as I don't want it to just be appended to the table but rather placed at a specific index. I thought I might be able to add it to my modelBuilder configuration, something like:
Property(p => p.Discontinued).HasColumnOrder(2);
but running Update-database does not appear to use it. Can this be done as a migration?

This is just a matter of missing functionality. SQL by itself does not rely on any implicit order of columns (with some exceptions: ORDER BY , ...).
Neither SQL Server nor ORACLE do have a direct SQL DDL command (aka ALTER TABLE...) to move a column around.
Therefore there's no possibility to change the order without high effort (recreate the table). See for example
How To change the column order of An Existing Table in SQL Server 2008
SQL SERVER – Change Order of Column In Database Tables
https://dba.stackexchange.com/questions/61978/how-to-change-the-column-order

Related

Entity Framework Core - Computed Column issue

I have an entity class with a column called 'CalculatedId'. This column is obtained from an SQL statement and the column does NOT exist in the database table.
If I run app I get an error telling me that the column does not exist. This error is due to the framework trying to map the column to a physical column.
Below is my mapping code:
modelBuilder
.Entity<Widgets>()
.Property(x => x.CalculatedId)
.HasComputedColumnSql("select top 1 Id from MyTable");
I thought that this would tell EF not to look for a physical column as it's generated.
The only way I can get rid of the error is if I do this:
modelBuilder
.Entity<Widgets>()
.Ignore(x => x.CalculatedId);
Problem there is that the column is totally ignored an not generated at all.
Can someone please connect the dots for me and clarify what needs to be done to make sure that the column is generated but EF does not look for it in the database.
NB: Has to be done in the fluent API, no data annotations.

Entity Framework: How can I assign permissions on new code first tables?

I think the question speaks for itself. I have a fairly typical case where I've created a new entity class on which I've specified the [Table] attribute. The Add-Migration command has generated the corresponding DbMigration.CreateTable, etc.
However, I would like to ensure that the table is create in SQL Server with the select permission assigned to group... let's call it ABCGRP.
Can this be done via attributes, the Fluent API or will I need to simply create a SQL script with a GRANT operation?

EF 6 automatic migration column name uppercase rename not detected

We are using EF6 code first approach and we have automatic migrations enabled (we are at the beginning of the project).
Database.SetInitializer(new MigrateDatabaseToLatestVersion<OurDbContext, Configuration>());
And in the Configuration class we have the following enabled in order for the DB to be updated automatically during each application start:
public Configuration()
{
AutomaticMigrationsEnabled = true;
AutomaticMigrationDataLossAllowed = true;
}
The DB column names are explicitly mapped like this (with "HasColumnName") because we want to have full control over the column names:
modelBuilder.Entity<User>().Property(u => u.Gender).IsRequired().HasColumnName("Gender");
I've just noticed today that when I changed the name of the mapped column to begin with a lowercase ex:
modelBuilder.Entity<User>().Property(u => u.Gender).IsRequired().HasColumnName("gender");
... the automatic migration does not detect this as a change to the DB and does nothing i.e. the DB column name stays the same ("Gender" with an uppercase g).
It was only after I changed the column name to another word ex:
modelBuilder.Entity<User>().Property(u => u.Gender).IsRequired().HasColumnName("genders");
...that caused the automatic migrations to actually change the column name in the DB, which indicates that somehow the check for column name is done in a case insensitive way.
Does anyone know if this is by design, or is this a bug in EF?
Additionally is there a way to force the automatic migrations to perform case sensitive column name checks?
Thanks in advance
Case sensitivity does not make much difference to DB, so I believe this is intentional.
If you don't like lowercase column name, just work around this:
Rename the column from "gender" to something like "genders". Add migration
Rename column back to "Gender". Add migration
Alternatively, you can manually edit generated migration code

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.

EF Code First: Migrating Database Initialized on Different Code Versions

I am using Entity Framework 5 RC, code first. I am struggling with migrating databases that were created on different versions of code. For example, Database A was created when table FooBar didn't exist. Database B was created after table FooBar was added to my model.
I have a migration written that adds the FooBar table. Is it my responsibility to check in the FooBar migration that the table doesn't exist before calling CreateTable? It seems that is the case since Database B doesn't have an entry for the FooBar migration and will attempt to run it.
At first the MigrationHistory table seemed like it would save me from adding these checks but since new databases won't have entries for migrations added before the database was created, I still need to do the checks myself. Is that the right way to go about it or am I missing something?
To get around an issue I had with adding Stored Procedures, I wrote a TSQL script to create a new table "_PreviousMigrationHistory" - which receives new entries from the "_MigrationHistory" table after my stored procedure scripts have run...
I did add a new column to both tables ( "VersionId", of INT - IDENTITY(1,1) ) which is what I use for comparison within my code.
This way you have the un-updated migration patterns available to you (__PreviousMigrationHistory), even after Code First Migrations have occurred.
Would this help?
**EDIT - sorry, I miss read the question. - Although I would think that new instances of the database would still go through the migration steps, which in turn should add the entries to the __MigrationHistory table?