Description:
Using MySQL 5.5.19, .Net Connector 6.6.5, VS2012, .Net 4.0 Client Profile, C# Visual Studio 2012 I am not able to use the automatic migration feature. I created a simple project and the database creation and migration initialzers work correctly using MSSQL, but the same code fails after switching to the MySQL .Net connector.
The MySQL database can be created automatically with the CreateDatabaseIfNotExists initializer and migrated one time with the MigrateDatabaseToLatestVersion intializer. But if the application is run again after the successful migration, an exception is thrown indicating that a duplicate column was created.
MySql.Data.MySqlClient.MySqlException was unhandled
HResult=-2147467259
Message=Duplicate column name 'NewColumn'
Source=MySql.Data
ErrorCode=-2147467259
Number=1060
StackTrace:
at MySql.Data.MySqlClient.MySqlStream.ReadPacket()
at MySql.Data.MySqlClient.NativeDriver.GetResult(Int32& affectedRow, Int64& insertedId)
at MySql.Data.MySqlClient.Driver.GetResult(Int32 statementId, Int32& affectedRows, Int64& insertedId)
at MySql.Data.MySqlClient.Driver.NextResult(Int32 statementId, Boolean force)
at MySql.Data.MySqlClient.MySqlDataReader.NextResult()
at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior behavior)
at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader()
at MySql.Data.MySqlClient.MySqlCommand.ExecuteNonQuery()
at System.Data.Entity.Migrations.DbMigrator.ExecuteSql(DbTransaction transaction, MigrationStatement migrationStatement)
at System.Data.Entity.Migrations.Infrastructure.MigratorBase.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)
at System.Data.Entity.Migrations.DbMigrator.AutoMigrate(String migrationId, XDocument sourceModel, XDocument targetModel, Boolean downgrading)
at System.Data.Entity.Migrations.Infrastructure.MigratorBase.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.MigratorBase.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()
at System.Data.Entity.MigrateDatabaseToLatestVersion`2.InitializeDatabase(TContext context)
at System.Data.Entity.Database.<>c__DisplayClass2`1.<SetInitializerInternal>b__0(DbContext c)
at System.Data.Entity.Internal.InternalContext.<>c__DisplayClass8.<PerformDatabaseInitialization>b__6()
at System.Data.Entity.Internal.InternalContext.PerformInitializationAction(Action action)
at System.Data.Entity.Internal.InternalContext.PerformDatabaseInitialization()
at System.Data.Entity.Internal.LazyInternalContext.<InitializeDatabase>b__4(InternalContext c)
at System.Data.Entity.Internal.RetryAction`1.PerformAction(TInput input)
at System.Data.Entity.Internal.LazyInternalContext.InitializeDatabaseAction(Action`1 action)
at System.Data.Entity.Internal.LazyInternalContext.InitializeDatabase()
at System.Data.Entity.Internal.InternalContext.Initialize()
at System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType)
at System.Data.Entity.Internal.Linq.InternalSet`1.Initialize()
at System.Data.Entity.Internal.Linq.InternalSet`1.get_InternalContext()
at System.Data.Entity.Internal.Linq.InternalSet`1.ActOnSet(Action action, EntityState newState, Object entity, String methodName)
at System.Data.Entity.Internal.Linq.InternalSet`1.Add(Object entity)
at System.Data.Entity.DbSet`1.Add(TEntity entity)
at SimpleEF.Form1.button1_Click(Object sender, EventArgs e) in c:\Users\cmwoody\Documents\Visual Studio 2012\Projects\SimpleEF\SimpleEF\Form1.cs:line 27
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(Form mainForm)
at SimpleEF.Program.Main() in c:\Users\cmwoody\Documents\Visual Studio 2012\Projects\SimpleEF\SimpleEF\Program.cs:line 24
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
How to repeat:
Steps to duplicate:
1. Create a project SimpleEF with Entity Framework 4.3.1 and MySql .Net 6.6.5
2. Create a context with one collection of class Item
namespace SimpleEF
{
class MyDatabase: DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//modelBuilder.Entity<Preferences>()
// .Property(d => d.StationName)
// .IsRequired()
// .HasColumnType("char");
}
public DbSet<MyItem> Items { get; set; }
}
}
3. Create a class
namespace SimpleEF
{
class MyItem
{
public int Id { get; set; }
public string Name { get; set; }
public string NewColumn { get; set; }
}
}
4. Create a connection string in App.config
<connectionStrings>
<clear />
<add name="MyDatabase" connectionString="server=localhost;userid=root;password=123;port=3306;database=asimpleef;pooling=false;" providerName="MySql.Data.MySqlClient" />
</connectionStrings>
5. Set the initializer at startup
static void Main()
{
//Database.SetInitializer<MyDatabase>(new CreateDatabaseIfNotExists<MyDatabase>());
Database.SetInitializer<MyDatabase>(new MigrateDatabaseToLatestVersion<MyDatabase, Configuration>());
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
6. Create a form with a single button
private void button1_Click(object sender, EventArgs e)
{
MyDatabase myDatabase = new MyDatabase();
MyItem newItem = new MyItem();
newItem.Name = "Name1";
myDatabase.Items.Add(newItem);
myDatabase.SaveChanges();
MessageBox.Show("Done");
}
7. Uncomment the initializer for creating the database and comment the migration one.
8. Delete the database if it exists, run the app and click the button. The database is created and a row is saved.
7. Comment the initializer for creating the database and uncomment the migration one.
9. Run the app and click the button. No error.
10. Modify the Item class by adding a field "NewColumn"
11. Run the app and click the button. The myitems table is updated.
12. Run the app again and the error occurs.
Suggested fix:
When running the app the second time no migration should be performed.