web-dev-qa-db-ja.com

EF6.1.3からEF6.2.0に更新すると、破棄されたオブジェクトにアクセスできないというエラーが発生します

私はSQLiteを使用しています。 WPFアプリケーションでエンティティフレームワーク6.1.3を問題なく使用できますが、6.2.0に更新すると、次のエラーが発生します。

Test method DataAccessLayerTests.GenericDataRepositoryTests.CRUD_On_Pipe threw exception: 
System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'SQLiteConnection'.
    at System.Data.SQLite.SQLiteConnection.CheckDisposed()
   at System.Data.SQLite.SQLiteConnection.get_State()
   at System.Data.Entity.Internal.RepositoryBase.CreateConnection()
   at System.Data.Entity.Migrations.History.HistoryRepository.QueryExists(String contextKey)
   at System.Data.Entity.Migrations.History.HistoryRepository.Exists(String contextKey)
   at System.Data.Entity.Migrations.History.HistoryRepository.GetPendingMigrations(IEnumerable`1 localMigrations)
   at System.Data.Entity.Migrations.DbMigrator.GetPendingMigrations()
   at Core.DatabaseContext.CreateAndSeedIfNotExists`1.InitializeDatabase(T context) in C:\Users\roadrunner\propulsimcs\Propulsim\Core\DatabaseContext.cs:line 40
   at System.Data.Entity.Internal.InternalContext.<>c__DisplayClassf`1.<CreateInitializationAction>b__e()
   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.Database.Initialize(Boolean force)
   at Core.DatabaseContext..ctor() in C:\Users\roadrunner\propulsimcs\Propulsim\Core\DatabaseContext.cs:line 114
   at DataAccessLayer.GenericDataRepository`1.GetAll(Expression`1[] navigationProperties) in C:\Users\roadrunner\propulsimcs\Propulsim\DataAccessLayer\GenericDataRepository.cs:line 16
   at DataAccessLayerTests.GenericDataRepositoryTests.CRUD_On_Pipe() in C:\Users\roadrunner\propulsimcs\Propulsim\DataAccessLayerTests\GenericDataRepositoryTests.cs:line 34




Debug Trace:
Native library pre-loader is trying to load native SQLite library "C:\Users\roadrunner\propulsimcs\Propulsim\DataAccessLayerTests\bin\Debug\x86\SQLite.Interop.dll"...

何か案は?

13
ferit

この問題は、RepositoryBaseクラスの変更と、SQLiteConnectionクラスによる IDbConnection.State プロパティの誤った(IMO)実装(代わりにObjectDisposedExceptionをスローする)が原因で発生します。破棄されたオブジェクトで呼び出されたときにConnectionState.Closedを返す)。

#398:Glimpseがインストールされている場合のコードファースト移行でのNullReferenceException で報告されているものと同じです。ステータスによると、EF6リポジトリですでに修正されていますが、残念ながらパッチを提供しないことにしたため、v6.3を待つ必要があります。この投稿にリンクしているSQLiteの問題についてはすでに報告しているので、彼らが考えを変えることができれば幸いです。

別のオプションは、SQLite開発に問題を報告し、そこから修正を待つことです。どちらの場合も、SQLiteまたはEF6側で修正を待つ必要があります。この問題は、標準のMigrateDatabaseToLatestVersion初期化子を使用しても再現可能であることに注意してください。

次の醜いリフレクションハックを使用して、これを回避することができました。

public override void InitializeDatabase(T context)
{
    base.InitializeDatabase(context);

    var _historyRepository = migrator.GetType().GetField("_historyRepository", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(migrator);
    var _existingConnection = _historyRepository.GetType().BaseType.GetField("_existingConnection", BindingFlags.Instance | BindingFlags.NonPublic);
    _existingConnection.SetValue(_historyRepository, null);

    var x = migrator.GetPendingMigrations();
    if (x.Any())
    {
        migrator.Update();
        Seed(context);
    }
}

元の例外はなくなりましたが、「プロバイダー 'System.Data.SQLiteのMigrationSqlGeneratorが見つかりません」という別の例外が発生しています。ターゲット移行構成クラスでSetSqlGeneratorメソッドを使用して、追加のSQLジェネレーターを登録します。 'これは、SQLiteEFサービスのMigrationSqlGeneratorの欠如に関連する別の問題だと思います。 6.1.3でそれをどのように解決したかによって、問題になる場合と問題にならない場合があります。

とにかく、私は上記のハックを使用することをお勧めしません。今のところ、foxの修正を待つか、6.1.3にダウングレードしてください。

10
Ivan Stoev

GlimpseDBにも影響する問題が修正されました: https://github.com/aspnet/EntityFramework6/pull/405

現在リリースを待っています。

2
ferit