问题描述
我有一个新的 .NET 4.0 控制台应用程序,它使用:
I have a new .NET 4.0 console application that uses:
- MySql 6.4.4.0
- 实体框架 4.2(代码优先)
- Visual Studio 2010
到目前为止,这是有效的.我可以很好地添加和读取数据库.
So far this works. I can add and read from the database fine.
现在,当我添加 TransactionScope 时,如下例所示:
Now, when I add TransactionScope, as in the following example:
public static void TestInsert() { using (TransactionScope scope = new TransactionScope()) { using (var context = new MyDbContext()) { // Create a test user DateTime dt = DateTime.Now; var user1 = new User { UserID = 1, UserName = "test" }; context.Users.Add(user1); <-- exception occurs here context.SaveChanges(); } } }
当我运行这个时,我收到错误:
When I run this, I get the error:
当前不支持多个同时连接或在同一事务内具有不同连接字符串的连接.
似乎即使是最新版本的 MySql 也不喜欢 TransactionScope 与 EntityFramework 一起工作.
It seems that even the latest version of MySql does not like TransactionScope working with EntityFramework.
我希望能够使用事务,尤其是在测试项目中,以便我可以回滚任何更改.
I want to be able to use transactions, especially in test projects so that I can roll back any changes.
知道如何解决或解决此问题吗?
Any idea how I can fix this or work around it?
完整的错误信息
System.Data.DataException was unhandled Message=An exception occurred while initializing the database. See the InnerException for details. Source=EntityFramework StackTrace: 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) InnerException: System.Data.EntityException Message=The underlying provider failed on Open. Source=System.Data.Entity StackTrace: at System.Data.EntityClient.EntityConnection.OpenStoreConnectionIf(Boolean openCondition, DbConnection storeConnectionToOpen, DbConnection originalConnection, String exceptionCode, String attemptedOperation, Boolean& closeStoreConnectionOnFailure) at System.Data.EntityClient.EntityConnection.Open() at System.Data.Objects.ObjectContext.EnsureConnection() at System.Data.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption) at System.Data.Objects.ObjectQuery`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator() at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source) at System.Data.Objects.ELinq.ObjectQueryProvider.<GetElementFunction>b__1[TResult](IEnumerable`1 sequence) at System.Data.Objects.ELinq.ObjectQueryProvider.ExecuteSingle[TResult](IEnumerable`1 query, Expression queryRoot) at System.Data.Objects.ELinq.ObjectQueryProvider.System.Linq.IQueryProvider.Execute[S](Expression expression) at System.Data.Entity.Internal.Linq.DbQueryProvider.Execute[TResult](Expression expression) at System.Linq.Queryable.FirstOrDefault[TSource](IQueryable`1 source) at System.Data.Entity.Internal.InternalContext.QueryForModelHash() at System.Data.Entity.Internal.InternalContext.CompatibleWithModel(Boolean throwIfNoMetadata) at System.Data.Entity.Database.CompatibleWithModel(Boolean throwIfNoMetadata) at System.Data.Entity.CreateDatabaseIfNotExists`1.InitializeDatabase(TContext context) at System.Data.Entity.Internal.InternalContext.<>c__DisplayClass5.<PerformDatabaseInitialization>b__3() at System.Data.Entity.Internal.InternalContext.PerformInitializationAction(Action action) InnerException: System.NotSupportedException Message=Multiple simultaneous connections or connections with different connection strings inside the same transaction are not currently supported. Source=MySql.Data StackTrace: at MySql.Data.MySqlClient.MySqlConnection.Open() at System.Data.EntityClient.EntityConnection.OpenStoreConnectionIf(Boolean openCondition, DbConnection storeConnectionToOpen, DbConnection originalConnection, String exceptionCode, String attemptedOperation, Boolean& closeStoreConnectionOnFailure) InnerException:
一些类(不复杂):
[Table("User")] public class User { public User() { } // Primary key [Key] public int UserID { get; set; } public string UserName { get; set; } } public class MyDbContext : DbContext { public MyDbContext() : base("DbContext") { } public DbSet<User> Users { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { // Tell Code First to ignore PluralizingTableName convention // If you keep this convention then the generated tables will have pluralized names. modelBuilder.Conventions.Remove<PluralizingTableNameConvention>(); } }
App.config:
<?xml version="1.0"?> <configuration> <connectionStrings> <clear/> <add name="DbContext" connectionString="Server=localhost; Database=****; Uid=****; Pwd=****;" providerName="MySql.Data.MySqlClient"/> </connectionStrings> <system.data> <DbProviderFactories> <remove invariant="MySql.Data.MySqlClient"/> <add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data"/> </DbProviderFactories> </system.data> </configuration>
提前致谢,
丹
推荐答案
试试这个,创建上下文后创建事务.
Try this, Create transaction after creating context.
public static void TestInsert() { using (var context = new MyDbContext()) { using (TransactionScope scope = new TransactionScope()) { // Create a test user DateTime dt = DateTime.Now; var user1 = new User { UserID = 1, UserName = "test" }; context.Users.Add(user1); context.SaveChanges(); scope.Complete(); } } }