Unfortunately I am using Entity Framework in my project. After migration support added to Entity Framework I thought using this feature may help me feel a little better about Entity Framework . But the way migration is implemented in EF shows that nothing has changed. Migration has lots of problems and bugs.
After carefully doing all the required cumbersome procedures Entity Framework migration failed to work and I found no workaround until I strangely faced the exception 'Invalid Object Name 'dbo.__MigrationHistory''. This exception give me a clue about the cause of my problems.
It seems that Entity Framework team do not use appropriate testing methods and they only care about the main courses and are very negligent about alternative cases. For example in this case they presumed that always the default schema is dbo. It creates __MigrationHistory on the default schema, but queries for it on the dbo schema.
After a while I find another problem. Entity Framework also tries to insert rows into __MigrationHistory without specifying schema name.
Ok, I wrote this code to make Entity Framework script generator apply 'dbo.' before the __MigrationHistory. I know this is naive solution but at least it works.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This is for scenarios in which your default schema name is not dbo and hence Entity Framework migration is not working properly. | |
// WARNING : Please be advised that this is a naive solution which its purpose is to just show how it could be corrected. You may not use this code without understanding and resolving any potential problem. | |
// For more information go to http://samondotnet.blogspot.com.au/2012/03/why-invalid-object-name.html | |
namespace ES.DataAccess.Migrations | |
{ | |
using System.Data.Entity.Migrations; | |
using System.Data.Entity.Migrations.Model; | |
using System.Data.Entity.Migrations.Sql; | |
using System.Linq; | |
internal sealed class Configuration : DbMigrationsConfiguration<ES.Domain.ExaminationDbContext> | |
{ | |
public Configuration() | |
{ | |
SetSqlGenerator("System.Data.SqlClient", new SamSqlGenerator()); | |
AutomaticMigrationsEnabled = false; | |
} | |
} | |
public class SamSqlGenerator : SqlServerMigrationSqlGenerator | |
{ | |
protected override void Generate(System.Data.Entity.Migrations.Model.CreateTableOperation createTableOperation) | |
{ | |
if (createTableOperation.Name.Contains("__MigrationHistory") && !createTableOperation.Name.StartsWith("dbo.")) | |
{ | |
var newCreateTableOperation = new CreateTableOperation("dbo." + createTableOperation.Name); | |
createTableOperation.Columns.ToList().ForEach(newCreateTableOperation.Columns.Add); | |
base.Generate(newCreateTableOperation); | |
} | |
else | |
base.Generate(createTableOperation); | |
} | |
protected override void GenerateMakeSystemTable(System.Data.Entity.Migrations.Model.CreateTableOperation createTableOperation) | |
{ | |
} | |
protected override void Generate(System.Data.Entity.Migrations.Model.InsertHistoryOperation insertHistoryOperation) | |
{ | |
if (!insertHistoryOperation.Table.StartsWith("dbo.")) | |
insertHistoryOperation = new InsertHistoryOperation("dbo." + insertHistoryOperation.Table, insertHistoryOperation.MigrationId, insertHistoryOperation.Model, null); | |
base.Generate(insertHistoryOperation); | |
} | |
} | |
} |
The same problem was present when MS introduced membership API for ASP.NET for the 1st time. They only know and support "dbo"'s!
ReplyDelete