問題が発生したときに、Entity Framework に適用されるリポジトリ パターンについていくつかのテストを行っていました。テスト目的で使用したい架空のホテルマネージャーソフトウェア(HotelManagerと呼ばれる)のコアレイヤーとデータレイヤーを(コードファーストで)実装し、DBへのテーブルの束に関連付けました。
これは構造です:
コア層は HotelManager.Core アセンブリに残り、以下が含まれます。
- すべてのモデル (「リバース エンジニア コード ファースト」ユーティリティで自動生成)
- IRepostiory インターフェイス (コア層へのリポジトリの抽象化に使用)
.
データ層は HotelManager.Data アセンブリに残り、以下が含まれます。
- すべてのモデル マッピング (「リバース エンジニア コード ファースト」ユーティリティで自動生成)
- すべてのリポジトリの実装
- コンテキスト (「リバース エンジニア コード ファースト」ユーティリティで自動生成)
- すべてのリポジトリを含む作業単位
ご覧のとおり、データ層は、クライアント アプリケーションがデータを操作するために使用する Unit of work クラスを公開しますが、ここで奇妙な動作に気付きました。実際、私の UoW に含まれるすべてのリポジトリは正しくロードされますが、操作の追加と削除はまったく機能しません!
例えば:
[TestMethod]
public void AddWontWork()
{
int firstCount = this._hotelManagerUoW.Utenti.AsEnumerable().Count();
AddUser();
int lastCount = this._hotelManagerUoW.Utenti.AsEnumerable().Count();
Assert.IsTrue(lastCount == firstCount + 1);
}
private void AddUser()
{
Utente utente = new Utente();
utente.Nome = "Alex";
utente.Cognome = "DeLarge";
utente.Indirizzo = "London st.";
utente.Nazione = "England";
utente.Password = "mypassword";
utente.Username = "MyUsername";
utente.ZipCode = "784521";
utente.Citta = "Coventry";
this._hotelManagerUoW.Utenti.Add(utente);
}
このテスト メソッドは失敗します。理由はわかりませんが、AddUser()
メソッドが呼び出された後でも (AddUser()
実際には新しいオブジェクトUtenti
のインスタンスがリポジトリに追加されます)、何も起こらなかったように に一致し、テストは失敗します! リポジトリによって管理されている DbSet に、新しく追加されたエンティティが見つかりません。リポジトリからエンティティを削除しても同じ結果になります。何も起こりません。これは、各 Add() または Remove() 操作の後に SaveChanges() メソッドを呼び出す場合にのみ機能しますが、データをロールバックする機会が必要であり、特定の場合にのみ DB と対話したいため、これは不可能です。 DB アクセスを最小限に抑えるための明確に定義されたケース。utente
lastCount
firstCount
これは EF の正しい動作ですか?私はその動作を完全に誤解していますか、それとも私のプロジェクトに何か問題がありますか? UtentiDbSet.Add(new Utente() with {....});
のようなものを実行すると、EF エンジンは新しい Utente オブジェクトを DbSet に「追加済み」状態で追加し (したがって、UtentiDbSet.Count() == 1)、次に SaveChanges() を呼び出すと常に考えていました。私のコンテキストでは、データは DB に永続化されます。
便宜上、プロジェクト全体をここにアップロードしました。
HotelManager.Data.Testというテスト プロジェクトがあります。メソッドが機能しているのになぜAddWontWork()
失敗するのか理解できませんAddWithSaveChangesWillWork()
。HotelManager.Data.Testプロジェクトの app.config で connectionString を設定することを忘れないでください(EF は、データ層に含まれるマッピングを使用して DB 構造全体を構築します)。
前もって感謝します。