EF5 Code First Migrations: "Column names in each table must be unique" error after using RenameColumn - entity-framework

We're using Entity Framework 5.0 Code First and Automatic Migrations.
I had a class like so:
public class TraversalZones
{
public int Low { get; set; }
public int High { get; set; }
}​
Then we realized these properties weren't really the right names, so we changed them:
public class TraversalZones
{
public int Left { get; set; }
public int Top { get; set; }
}​
The rename refactored properly throughout the project, but I know Automatic Migrations aren't smart enough to pick up these explicit renames in the IDE, so I first checked to verify the only pending migration was this column rename:
update-database -f -script
Sure enough it just showed the SQL dropping Low and High and adding Left and Top. I then added a manual migration:
add-migration RenameColumns_TraversalZones_LowHigh_LeftTop
And fixed up the generated code to simply:
public override void Up()
{
RenameColumn("TraversalZones", "Low", "Left");
RenameColumn("TraversalZones", "High", "Top");
}
public override void Down()
{
RenameColumn("TraversalZones", "Left", "Low");
RenameColumn("TraversalZones", "Top", "High");
}
​
I then updated the db:
update-database -verbose
And got 2 column renames, just like I was expecting.
Several migrations later I backed up Production and Restored it to a local DB to test the code on this DB. This DB had the TraversalZones table already created in it, with the old column names (Low and High) I of course began by updating it:
update-database -f -verbose
And the rename commands appeared in the output - all appeared well:
EXECUTE sp_rename #objname = N'TraversalZones.Low', #newname = N'Left', #objtype = N'COLUMN'
EXECUTE sp_rename #objname = N'TraversalZones.High', #newname = N'Top', #objtype = N'COLUMN'
[Inserting migration history record]
I then ran my code, and it errored out telling me the database had changed since last run, and that I should run update-database... .
So I ran it again:
update-database -f -verbose
And am now stuck on this error:
No pending code-based migrations. Applying automatic migration:
201212191601545_AutomaticMigration.
ALTER TABLE [dbo].[TraversalZones] ADD [Left] [int] NOT NULL DEFAULT 0
System.Data.SqlClient.SqlException (0x80131904): Column names in each table must be unique. Column name 'Left' in table 'dbo.TraversalZones' is specified more than once.
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
at System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean async, Int32 timeout)
at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean asyncWrite)
at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
at System.Data.Entity.Migrations.DbMigrator.ExecuteSql(DbTransaction transaction, MigrationStatement migrationStatement)
at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.ExecuteSql(DbTransaction transaction, MigrationStatement migrationStatement)
at System.Data.Entity.Migrations.DbMigrator.ExecuteStatements(IEnumerable`1 migrationStatements)
at System.Data.Entity.Migrations.Infrastructure.MigratorBase.ExecuteStatements(IEnumerable`1 migrationStatements)
at System.Data.Entity.Migrations.DbMigrator.ExecuteOperations(String migrationId, XDocument targetModel, IEnumerable`1 operations, Boolean downgrading, Boolean auto)
at System.Data.Entity.Migrations.DbMigrator.AutoMigrate(String migrationId, XDocument sourceModel, XDocument targetModel, Boolean downgrading)
at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.AutoMigrate(String migrationId, XDocument sourceModel, XDocument targetModel, Boolean downgrading)
at System.Data.Entity.Migrations.DbMigrator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId)
at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId)
at System.Data.Entity.Migrations.DbMigrator.Update(String targetMigration)
at System.Data.Entity.Migrations.Infrastructure.MigratorBase.Update(String targetMigration)
at System.Data.Entity.Migrations.Design.ToolingFacade.UpdateRunner.RunCore()
at System.Data.Entity.Migrations.Design.ToolingFacade.BaseRunner.Run()
ClientConnectionId:c40408ee-def3-4553-a9fb-195366a05fff
Column names in each table must be unique. Column name 'Left' in table 'dbo.TraversalZones' is specified more than once.​
So, clearly Migrations is confused as to whether the column "Left" still needs to make it into this table; I would assume RenameColumn would leave things in the proper state, but it appears it has not.
When I dump what it's attempting to do to a update-database -f -script, I get it trying to do exactly what it would have done if the manual migration were not there:
ALTER TABLE [dbo].[TraversalZones] ADD [Left] [int] NOT NULL DEFAULT 0
ALTER TABLE [dbo].[TraversalZones] ADD [Top] [int] NOT NULL DEFAULT 0
DECLARE #var0 nvarchar(128)
SELECT #var0 = name
FROM sys.default_constraints
WHERE parent_object_id = object_id(N'dbo.TraversalZones')
AND col_name(parent_object_id, parent_column_id) = 'Low';
IF #var0 IS NOT NULL
EXECUTE('ALTER TABLE [dbo].[TraversalZones] DROP CONSTRAINT ' + #var0)
ALTER TABLE [dbo].[TraversalZones] DROP COLUMN [Low]
DECLARE #var1 nvarchar(128)
SELECT #var1 = name
FROM sys.default_constraints
WHERE parent_object_id = object_id(N'dbo.TraversalZones')
AND col_name(parent_object_id, parent_column_id) = 'High';
IF #var1 IS NOT NULL
EXECUTE('ALTER TABLE [dbo].[TraversalZones] DROP CONSTRAINT ' + #var1)
ALTER TABLE [dbo].[TraversalZones] DROP COLUMN [High]
INSERT INTO [__MigrationHistory] ([MigrationId], [Model], [ProductVersion]) VALUES ('201212191639471_AutomaticMigration', 0x1F8B08000...000, '5.0.0.net40')
This appears to be a bug in Migrations.

The workaround, obviously, is this:
update-database -f -script
Which you can see the results of in my question. Then I tossed everything from the script but the last line, and ran that against the DB to let Migrations know: We already renamed that column, cut it out.
I can now proceed with this copy of the database, but I'm concerned every migration against copies of Production (until Production itself has been migrated) will keep having this issue. How can I resolve this properly without this workaround?
Update
This was in fact an issue in every other instance including Production. The dirty solution was to generate a SQL script (update-database -f -script), after committing the generated version and the fixed version.
A slightly cleaner solution is to take the SQL from the script, add a manual migration, and change the contents of Up to simply:
public void Up()
{
Sql("...That SQL you extracted from the script...");
}
This will ensure other environments running this migration do so precisely the way you intended.
Testing this is a bit tricky so you can approach it this way:
Backup your db just in case.
Run the SQL. If it works properly, set the SQL aside.
Add the manual migration and wipe out everything in the Up() method. Leave it completely empty.
Run update-database -f
Now modify the Up() method by adding the Sql("..."); calling the SQL you set aside.
Now your db is up to date without running the SQL twice, and other environments get the results of that SQL.

Related

Entity Framework Core 7 database upon first initializing returns error "Object reference not set to an instance of an object"

I am using the following command to import a database into Entity Framework Core 7:
Scaffold-DbContext -connection name=constring Microsoft.EntityFrameworkCore.SqlServer -Output Models
Here is the connection string in my appsettings.json:
"ConnectionStrings": {
"constring": "Server=.\\SQLExpress;Database=Words;Trusted_Connection=True; TrustServerCertificate=True"
}
and this is the error:
Scaffold-DbContext -connection name=constring Microsoft.EntityFrameworkCore.SqlServer -Output Models
Build started...
Build succeeded.
System.NullReferenceException: Object reference not set to an instance of an object.
at Microsoft.EntityFrameworkCore.Scaffolding.Internal.CSharpDbContextGenerator.TransformText()
at Microsoft.EntityFrameworkCore.Scaffolding.Internal.CSharpModelGenerator.ProcessTemplate(ITextTransformation transformation)
at Microsoft.EntityFrameworkCore.Scaffolding.Internal.CSharpModelGenerator.GenerateModel(IModel model, ModelCodeGenerationOptions options)
at Microsoft.EntityFrameworkCore.Scaffolding.Internal.ReverseEngineerScaffolder.ScaffoldModel(String connectionString, DatabaseModelFactoryOptions databaseOptions, ModelReverseEngineerOptions modelOptions, ModelCodeGenerationOptions codeOptions)
at Microsoft.EntityFrameworkCore.Design.Internal.DatabaseOperations.ScaffoldContext(String provider, String connectionString, String outputDir, String outputContextDir, String dbContextClassName, IEnumerable`1 schemas, IEnumerable`1 tables, String modelNamespace, String contextNamespace, Boolean useDataAnnotations, Boolean overwriteFiles, Boolean useDatabaseNames, Boolean suppressOnConfiguring, Boolean noPluralize)
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.ScaffoldContextImpl(String provider, String connectionString, String outputDir, String outputDbContextDir, String dbContextClassName, IEnumerable`1 schemaFilters, IEnumerable`1 tableFilters, String modelNamespace, String contextNamespace, Boolean useDataAnnotations, Boolean overwriteFiles, Boolean useDatabaseNames, Boolean suppressOnConfiguring, Boolean noPluralize)
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.ScaffoldContext.<>c__DisplayClass0_0.<.ctor>b__0()
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>c__DisplayClass3_0`1.<Execute>b__0()
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
EDIT-
In response to some of the comments, I am quite aware that entityframeworkcore is not a db. I was not importing data-I have another app that's doing that. I did resovlve this btw-I modified the entity classes, deleted the tables in the db, deleted all the previous migrations, added migrations, updated the database using the dotnet cli, and worked.

How can I get table descriptions from Azure SQL Database

For SQL Server, I can get table descriptions from the metadata using:
SELECT
OBJECT_SCHEMA_NAME(t.object_id) as SchemaName,
t.name AS TableName,
ex.value AS Description
FROM
sys.tables AS t,
sys.extended_properties AS ex
WHERE
ex.major_id = t.object_id
AND ex.minor_id = 0
AND ex.name = 'MS_Description'
AND ex.value IS NOT NULL
But that throws an exception hitting an Azure SQL Database. How can I pull it from Azure SQL Database?
The exception I am getting is:
System.Data.SqlClient.SqlException occurred HResult=-2146232060
Message=Invalid object name 'sys.extended_properties'. Source=.Net
SqlClient Data Provider ErrorCode=-2146232060 Class=16
LineNumber=1 Number=208 Procedure=""
Server=tcp:odjidszumt.database.windows.net State=1 StackTrace:
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action1 wrapCloseInAction)
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException
exception, Boolean breakConnection, Action1 wrapCloseInAction)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject
stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream,
BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject
stateObj, Boolean& dataReady)
at System.Data.SqlClient.SqlDataReader.TryConsumeMetaData()
at System.Data.SqlClient.SqlDataReader.get_MetaData()
at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds,
RunBehavior runBehavior, String resetOptionsString)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior
cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean
async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader
ds)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior
cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String
method, TaskCompletionSource`1 completion, Int32 timeout, Task& task,
Boolean asyncWrite)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior
cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String
method)
at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior
behavior, String method)
at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior
behavior)
at System.Data.Common.DbCommand.ExecuteReader()
at net.windward.utils.ado.SqlServer.WrSqlServerDatabase.TableDesc(DbConnection
conn, String select) in
c:\vso\Jenova\team\refactoring\Engine\DotNetEngine\Kailua\net\windward\utils\ado\SqlServer\WrSqlServerDatabase.cs:line
465 InnerException:
I have no idea what version of Sql Database - we created a Sql Database on Azure and didn't do anything special so I'm guessing the latest.
Officially, according to this MSDN article, sys.extended_properties view is not supported in Azure SQL Database. The error message you provided says "Invalid object name 'sys.extended_properties'", which proved it's not supported.
However, the weird thing is that when I run the query from SSMS and SQL Server Object Explorer against an Azure SQL Database, it works. I then go back to the portal and notice that I created a V12 SQL Server, I then tried creating a V2 SQL Server and run the query against it, get the same result "Invalid object name 'sys.extended_properties'", see below snapshot:
So as per above test, I think 'sys.extended_properties' is only supported in Azure SQL Server V12 database. It seems MS official article might not be updated to the lastest. I'd suggest you check which version of Azure SQL Database you've created:
You can enable V12 when creating the SQL Server as below:
Found the Azure sys tables. I needed a solution to set columns requiring case sensitive comparison during a meta driven etl process. NOTE: might want to convert the d.[Value] field to something meta-model ingestible.
/*********************************
Returns Table Column Descriptions
*********************************/
Select
s.[name] AS SchemaName
,t.[name] AS TableName
,c.[name] AS ColumnName
,d.[value] AS Desription
From sys.schemas AS s
Inner Join sys.sysobjects AS t /* Tables*/
On t.[uid] = s.[schema_id]
Inner Join sys.syscolumns AS c
On c.id = t.id
Inner Join sys.extended_properties AS d /*Column Description*/
On d.major_id = t.id
And d.minor_id = c.colid
Where d.[name] = 'MS_Description'

EF CodeFirst-Migration on copied database want to run initial migration

I copied a database from production. The difference with my Dev-DB in terms of tables / fields is just one field. That field gets added by the last code-first migration. The only migration that was not applied in production.
Now I copied an Azure DB to a local SQLExpress on my dev machine through an export import of the DB in a SQL-script (schema + data). The application runs fine as long a I do not need that one field of course. I wanted to add that field by running 'Update-Database' and apparantly VS wants to apply to first 'initial' migration. Why ? I checked the db for the __MigrationHistory table, it has it and the only record that is missing is the one than has the migrationid from that very last migration.
Any help to understand what is going on and to solve it is appreciated. How is VS update-database determining which migration it should apply ?
UPDATE:
EF6
Output of update-database -verbose
PM> update-database -verbose
Using StartUp project 'Mapato'.
Using NuGet project 'Mapato'.
Specify the '-Verbose' flag to view the SQL statements being applied to the target database.
Target database is: 'MapatoCopyProductie' (DataSource: localhost\SQLEXPRESS_JSL, Provider: System.Data.SqlClient, Origin: Configuration).
Applying explicit migrations: [201505170635248_Init, 201505191015284_[ActivityMaster] Added Duration, ...........
<continued list of all migrations>
Applying explicit migration: 201505170635248_Init.
CREATE TABLE [dbo].[Activities] (
[Id] [int] NOT NULL IDENTITY,
[TenantId] [int] NOT NULL,
[IsActive] [bit] NOT NULL,
[WorkYearId] [int] NOT NULL,
[EnrollMentFee] [int] NOT NULL,
[Currency] [int] NOT NULL,
[RequiredAgreementId] [int],
[ActivityMasterId] [int] NOT NULL,
[Info] [nvarchar](max),
CONSTRAINT [PK_dbo.Activities] PRIMARY KEY ([Id])
)
System.Data.SqlClient.SqlException (0x80131904): There is already an object named 'Activities' in the database.
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
at System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean async, Int32 timeout, Boolean asyncWrite)
at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean asyncWrite)
at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.<NonQuery>b__0(DbCommand t, DbCommandInterceptionContext`1 c)
at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget target, Func`3 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed)
at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.NonQuery(DbCommand command, DbCommandInterceptionContext interceptionContext)
at System.Data.Entity.Internal.InterceptableDbCommand.ExecuteNonQuery()
at System.Data.Entity.Migrations.DbMigrator.ExecuteSql(MigrationStatement migrationStatement, DbConnection connection, DbTransaction transaction, DbInterceptionContext interceptionContext)
at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.ExecuteSql(MigrationStatement migrationStatement, DbConnection connection, DbTransaction transaction, DbInterceptionContext interceptionContext)
at System.Data.Entity.Migrations.DbMigrator.ExecuteStatementsInternal(IEnumerable`1 migrationStatements, DbConnection connection, DbTransaction transaction, DbInterceptionContext interceptionContext)
at System.Data.Entity.Migrations.DbMigrator.ExecuteStatementsWithinTransaction(IEnumerable`1 migrationStatements, DbTransaction transaction, DbInterceptionContext interceptionContext)
at System.Data.Entity.Migrations.DbMigrator.ExecuteStatementsWithinNewTransaction(IEnumerable`1 migrationStatements, DbConnection connection, DbInterceptionContext interceptionContext)
at System.Data.Entity.Migrations.DbMigrator.ExecuteStatementsInternal(IEnumerable`1 migrationStatements, DbConnection connection, DbInterceptionContext interceptionContext)
at System.Data.Entity.Migrations.DbMigrator.ExecuteStatementsInternal(IEnumerable`1 migrationStatements, DbConnection connection)
at System.Data.Entity.Migrations.DbMigrator.<>c__DisplayClass30.<ExecuteStatements>b__2e()
at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.<>c__DisplayClass1.<Execute>b__0()
at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1 operation)
at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute(Action operation)
at System.Data.Entity.Migrations.DbMigrator.ExecuteStatements(IEnumerable`1 migrationStatements, DbTransaction existingTransaction)
at System.Data.Entity.Migrations.DbMigrator.ExecuteStatements(IEnumerable`1 migrationStatements)
at System.Data.Entity.Migrations.Infrastructure.MigratorBase.ExecuteStatements(IEnumerable`1 migrationStatements)
at System.Data.Entity.Migrations.DbMigrator.ExecuteOperations(String migrationId, VersionedModel targetModel, IEnumerable`1 operations, IEnumerable`1 systemOperations, Boolean downgrading, Boolean auto)
at System.Data.Entity.Migrations.DbMigrator.ApplyMigration(DbMigration migration, DbMigration lastMigration)
at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.ApplyMigration(DbMigration migration, DbMigration lastMigration)
at System.Data.Entity.Migrations.DbMigrator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId)
at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId)
at System.Data.Entity.Migrations.DbMigrator.UpdateInternal(String targetMigration)
at System.Data.Entity.Migrations.DbMigrator.<>c__DisplayClassc.<Update>b__b()
at System.Data.Entity.Migrations.DbMigrator.EnsureDatabaseExists(Action mustSucceedToKeepDatabase)
at System.Data.Entity.Migrations.Infrastructure.MigratorBase.EnsureDatabaseExists(Action mustSucceedToKeepDatabase)
at System.Data.Entity.Migrations.DbMigrator.Update(String targetMigration)
at System.Data.Entity.Migrations.Infrastructure.MigratorBase.Update(String targetMigration)
at System.Data.Entity.Migrations.Design.ToolingFacade.UpdateRunner.Run()
at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate)
at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate)
at System.Data.Entity.Migrations.Design.ToolingFacade.Run(BaseRunner runner)
at System.Data.Entity.Migrations.Design.ToolingFacade.Update(String targetMigration, Boolean force)
at System.Data.Entity.Migrations.UpdateDatabaseCommand.<>c__DisplayClass2.<.ctor>b__0()
at System.Data.Entity.Migrations.MigrationsDomainCommand.Execute(Action command)
ClientConnectionId:913026de-19a7-4ba5-83ea-dc5403995540
Error Number:2714,State:6,Class:16
There is already an object named 'Activities' in the database.
PM>
I got it to work again. I do not understand why it works now, but that's what I did :
from another post I learned that it was worthwhile checking the origin in :
Target database is: 'MapatoCopyProductie' (DataSource: localhost\SQLEXPRESS_JSL, Provider: System.Data.SqlClient, Origin: Configuration)
I noticed that the name was configuration. I re-factored the configuration class to a more meaningfullname, so I would have expected that name there. Changed it back to configuration and I works again. Guess it has to do with 'convention over configuration' and if nof 'configuration class' is found it chooses some default that did collide with what needed to be done.

EF code first migration error "Object has been disconnected or does not exist at the server"

I am using Entity Framework 6.1.1 on SQL Server 2008 and I have a long running code first migration (about 20 minutes). It gets to the end and then gives the following error.
System.Runtime.Remoting.RemotingException: Object '/f10901d8_94fe_4db4_bb9d_51cd19292b01/bq6vk4vkuz5tkri2x8nwhsln_106.rem' has been disconnected or does not exist at the server.
at System.Data.Entity.Migrations.Design.ToolingFacade.ToolLogger.Verbose(String sql)
at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.ExecuteSql(DbTransaction transaction, MigrationStatement migrationStatement, DbInterceptionContext interceptionContext)
at System.Data.Entity.Migrations.DbMigrator.ExecuteStatementsInternal(IEnumerable`1 migrationStatements, DbTransaction transaction, DbInterceptionContext interceptionContext)
at System.Data.Entity.Migrations.DbMigrator.ExecuteStatementsInternal(IEnumerable`1 migrationStatements, DbConnection connection)
at System.Data.Entity.Migrations.DbMigrator.<>c__DisplayClass30.<ExecuteStatements>b__2e()
at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.<>c__DisplayClass1.<Execute>b__0()
at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1 operation)
at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute(Action operation)
at System.Data.Entity.Migrations.DbMigrator.ExecuteStatements(IEnumerable`1 migrationStatements, DbTransaction existingTransaction)
at System.Data.Entity.Migrations.DbMigrator.ExecuteStatements(IEnumerable`1 migrationStatements)
at System.Data.Entity.Migrations.Infrastructure.MigratorBase.ExecuteStatements(IEnumerable`1 migrationStatements)
at System.Data.Entity.Migrations.DbMigrator.ExecuteOperations(String migrationId, XDocument targetModel, IEnumerable`1 operations, IEnumerable`1 systemOperations, Boolean downgrading, Boolean auto)
at System.Data.Entity.Migrations.DbMigrator.ApplyMigration(DbMigration migration, DbMigration lastMigration)
at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.ApplyMigration(DbMigration migration, DbMigration lastMigration)
at System.Data.Entity.Migrations.DbMigrator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId)
at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId)
at System.Data.Entity.Migrations.DbMigrator.UpdateInternal(String targetMigration)
at System.Data.Entity.Migrations.DbMigrator.<>c__DisplayClassc.<Update>b__b()
at System.Data.Entity.Migrations.DbMigrator.EnsureDatabaseExists(Action mustSucceedToKeepDatabase)
at System.Data.Entity.Migrations.Infrastructure.MigratorBase.EnsureDatabaseExists(Action mustSucceedToKeepDatabase)
at System.Data.Entity.Migrations.DbMigrator.Update(String targetMigration)
at System.Data.Entity.Migrations.Infrastructure.MigratorBase.Update(String targetMigration)
at System.Data.Entity.Migrations.Design.ToolingFacade.UpdateRunner.Run()
at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate)
at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate)
at System.Data.Entity.Migrations.Design.ToolingFacade.Run(BaseRunner runner)
at System.Data.Entity.Migrations.Design.ToolingFacade.Update(String targetMigration, Boolean force)
at System.Data.Entity.Migrations.UpdateDatabaseCommand.<>c__DisplayClass2.<.ctor>b__0()
at System.Data.Entity.Migrations.MigrationsDomainCommand.Execute(Action command)
The point of the migration is to update a field in the database that stores the MIME type of some binary data. It loops through every row, reads the binary data, attempts to determine what kind of content it is, then writes the appropriate MIME type value into the that row.
The script below uses ADO.NET to generate a list of update statements to run. I use ADO.NET because I must use .NET's imaging libraries (System.Drawing.Imaging.ImageFormat) to determine the type of binary content in each row (it'll be a jpeg, png, or pdf).
public override void Up()
{
List<string> updateStatements = new List<string>();
using(SqlConnection conn = new SqlConnection(ConfigurationManager.AppSettings["ConnectionString"]))
{
SqlCommand cmd = new SqlCommand("SELECT Table1ID, Image FROM Table1"), conn);
conn.Open();
//read each record and update the content type value based on the type of data stored
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
long idValue = Convert.ToInt64(reader["Table1ID"]);
byte[] data = (byte[])reader["Image"];
string contentType = GetMimeType(data);
updateStatements.Add(string.Format("UPDATE Table1 SET Content_Type = {0} WHERE Table1ID = {1}", contentType, idValue));
}
}
}
foreach (string updateStatement in updateStatements)
Sql(updateStatement);
}
public string GetMimeType(byte[] document)
{
if (document != null && document.Length > 0)
{
ImageFormat format = null;
try
{
MemoryStream ms = new MemoryStream(document);
Image img = Image.FromStream(ms);
format = img.RawFormat;
}
catch (Exception)
{
/* PDF documents will throw exceptions since they aren't images but you can check if it's really a PDF
* by inspecting the first four bytes with will be 0x25 0x50 0x44 0x46 ("%PDF"). */
if (document[0] == 0x25 && document[1] == 0x50 && document[2] == 0x44 && document[3] == 0x46)
return PDF;
else
return NULL;
}
if (format.Equals(ImageFormat.Jpeg))
{
return JPG;
}
else if (format.Equals(System.Drawing.Imaging.ImageFormat.Png))
{
return PNG;
}
}
return NULL;
}
I've seen this five year old post and the articles that it links to do not seem to exist anymore. At least I can't find them.
Does anyone know what's going on here?
-- UPDATE --
This appears to have something to do with how long the migration takes to run. I created a migration that does absolutely nothing other than sleep for 22 minutes
public override void Up()
{
System.Threading.Thread.Sleep(1320000);
}
and I got the same error. So it appears to be a timeout thing. I'm not 100% what object on the server they are referring to and I can't find much on this issue as it relates to code first migrations.
I tried setting the CommandTimeout property in the migrations Configuration.cs file to 5000 but it didn't help. I also attempted to set the SQL Server's Remove query timeout setting to 0 to prevent any timeouts but it didn't help either.
Poached from [GitHub EntityFramework 6 Issue #96][https://github.com/aspnet/EntityFramework6/issues/96#issuecomment-289782427]
The issue is that the ToolLogger lease lifetime (base class
MigrationsLogger is a MarshalByRefObject) is at the default (5
minutes). The ToolingFacade creates the logger, which lives in the
main program's app domain. The migrations run in a different app
domain. If a migration takes longer than 5 minutes, the attempt to log
any further information results in this error. A solution would be to
increase the lease lifetime in the main program. So... in the main
program, prior to creating the ToolingFacade, set the lease lifetime
to a longer time period:
using System.Runtime.Remoting.Lifetime;
...
LifetimeServices.LeaseTime = TimeSpan.FromHours(1);
It's a known issue in Entity Framework 6 for scripts that take a long time to complete.
A workaround is to generate only SQL script via the Update-Database command and execute the generated SQL directly on the SQL Server. In order to generate only the SQL you have to use the -Script flag:
Update-Database -Script
This has been causing us headaches. The problem appears to be due to the design of the EF migration utility. The program creates a new AppDomain in which to run migrations. The logging for the new AppDomain is handled in the original AppDomain (which is why remoting gets involved). Apparently the logger gets GC'ed if an individual migration takes too much time. I've verified this by replacing all the logger calls with Console.WriteLine - which makes the problem go away. There may be a fix by altering the migrate.exe tool (but may possibly require altering EntityFramework assembly itself).
I had this problem because the connection string in my web.config was pointing to the wrong server name.
Actually, I had to change my c:\windows\system32\drivers\etc\host file to specify correct IP address for this DB host name.
Just make sure your DB server is accessible.

Code First Migrations - Update-database -script command generated SQL script not working

I have to created a database through Entity Framework 5 with the following model:
public class Post
{
public int PostId { get; set; }
[MaxLength(200)]
public string Title { get; set; }
public string Content { get; set; }
public int BlogId { get; set; }
public Blog Blog { get; set; }
}
Then I have added new property in Post
public string Abstract { get; set; }
then I have run
Add-Migration AddPostAbstract
which created the following class in my Migrations folder, after that I have modified this file by adding one more SQL statement
//201308300714477_AddPostAbstract.cs
public override void Up()
{
AddColumn("dbo.Posts", "Abstract", c => c.String());
Sql("UPDATE dbo.Posts SET Abstract = LEFT(Content, 100) WHERE Abstract IS NULL");
}
public override void Down()
{
DropColumn("dbo.Posts", "Abstract");
}
After that I have executed this command
Update-Database –Verbose
which updated my database and also returned this SQL query:
ALTER TABLE [dbo].[Posts] ADD [Abstract] [nvarchar](max)
UPDATE dbo.Posts SET Abstract = LEFT(Content, 100) WHERE Abstract IS NULL
Now I have deleted Abstract column from table and tried to execute the above query manually in SQL at that time it show me following error.
Msg 207, Level 16, State 1, Line 2
Invalid column name 'Abstract'.
My question is why this query is not executed in SQL even this query is generated through migration?
Or is there any way to run such multiple query through migration generated script.
The -Verbose output just shows a summary of statements. If you run your command manually in SQL Server Management Studio then you need a GO between the two statements:
ALTER TABLE [dbo].[Posts] ADD [Abstract] [nvarchar](max)
GO
UPDATE dbo.Posts SET Abstract = LEFT(Content, 100) WHERE Abstract IS NULL
The quick fix is to do something like:
update-database -script
then use Sql Server management Studio to do the following search and replace in the generated script:
find what: ^{:b*}{{INSERT|UPDATE|SELECT|DELETE}.+} (this finds any CRUD statements)
replace with: \1GO\n\1\2\n (keep the indents, and add GO before any CRUD statements)
Find options: Use regular expressions
But, note that -Verbose doesn't give you the output you want, you need the output from -Script, or you will be missing the inserted data for the __MigrationHistory history table which could cause your application to throw an error when it runs (see below for details).
Details
Your comment below about the information on the MSDN Code First Migrations page is interesting. The page actually states (under the section "Getting a SQL Script")
Run the Update-Database command but this time specify the –Script flag
If you do this you will see something like:
ALTER TABLE [dbo].[Posts] ADD [Abstract] [nvarchar](max)
UPDATE dbo.Posts SET Abstract = LEFT(Content, 100) WHERE Abstract IS NULL
INSERT INTO [__MigrationHistory] ([MigrationId], [Model], [ProductVersion]) VALUES ( ...
The INSERT is important - this is how your EF in your application will know it is using the latest db version (and will therefore run instead of showing you an error). But, it is still missing that GO command. SQL server therefore tries to compile the 3 lines as a single batch and fails.
After adding the GO statements you need, you can still run this in a single transaction by surrounding it with:
BEGIN TRANSACTION;
BEGIN TRY
--Your migration code, with GO statements
END TRY
BEGIN CATCH
SELECT
ERROR_NUMBER() AS ErrorNumber
,ERROR_SEVERITY() AS ErrorSeverity
,ERROR_STATE() AS ErrorState
,ERROR_PROCEDURE() AS ErrorProcedure
,ERROR_LINE() AS ErrorLine
,ERROR_MESSAGE() AS ErrorMessage;
IF ##TRANCOUNT > 0
ROLLBACK TRANSACTION;
END CATCH;
IF ##TRANCOUNT > 0
COMMIT TRANSACTION;
GO
If you are frustrated because you are generating large scripts, putting a GO at the end of any ALTER TABLE line is trivial with replace in SSMS, which would be something like the one at the top of this answer