0

MVCアプリケーションでEntityFrameworkでリポジトリパターンを使用してレコードを更新しようとしていますが、db.SaveChanges()メソッドがデータベースに保存されません。私はエラーが発生していないので、コードをステップ実行して、正しい変数が渡され、レコード変数が更新されるのを確認することができます。エンティティフレームワークとレコードを更新するMVCリポジトリパターン

私が読んできた内容に基づいて、自分のデータベースコンテキスト(MyDBEntities)のインスタンスが2つあることが問題だと思います。問題は、MyDBEntitiesのインスタンスを作成するReadRepositoryが、MyDBEntitiesインスタンスも作成するWriteRepositoryに挿入されている可能性があります。エンティティをリポジトリに挿入する方法が本当にわかりません(これを想定していると仮定します)。

db.SaveChanges()の前にdb.MyTable.Attach(record);のようなものを追加しようとすると、私はMyDBEntities()を注入する必要があると考えられます。

An entity object cannot be referenced by multiple instances of IEntityChangeTracker.

CONTROLLER

public class MyController : Controller 
{ 
    private IWriteRepository _writeRepository; 

    public MyController(IWriteRepository writeRepository) 
    { 
     _writeRepository = writeRepository; 
    } 

    [HttpPost] 
    public ActionResult MyPostMethod(MyViewModel model) 
    { 
     try 
     { 
      //Send to the repository to edit a record 
      writeRepository.EditRecord(model); 

      return new HttpStatusCodeResult(HttpStatusCode.OK); 
     } 
     catch 
     { 
      throw new HttpException(500, "Internal Server Error"); 
     }    
    } 
} 

WRITEリポジトリ

//The ReadRepository is injected into the WriteRepository to grab records from the database 
public class WriteRepository : IWriteRepository 
{ 
    private MyDBEntities db = new MyDBEntities(); 
    private IReadRepository _readRepository; 

    public WriteRepository(IReadRepository readeadRepository) 
    { 
     _readRepository = readRepository; 
    }   

    public void EditRecord(MyViewModel model) 
    { 
     //Get the specific record to be updated 
     var record = readRepository.GetRecord(model.ID); 

     //Update the data 
     record.FirstName = model.Name; 

     //This isn't saving 
     db.SaveChanges(); 
    } 
} 

READリポジトリ

01あなたの MyControllerコードから
public class ReadRepository : IReadRepository 
{ 
    private MyDBEntities db = new MyDBEntities(); 

    //Provides the record to the write repository to edit 
    public MyTable GetRecord(int ID) 
    { 
     var record = (from t in db.MyTable 
         where t.ID == ID 
         select t).SingleOrDefault(); 

     return record; 
    } 
} 
+0

[エンティティオブジェクトの可能な重複はIEntityChangeTrackerの複数のインスタンスによって参照できません。 Entity Framework 4.1のエンティティに関連するオブジェクトを追加しています](http://stackoverflow.com/questions/10191734/entity-object-cannot-be-referenced-by-multiple-instances-ofientitychangetracker) –

+0

私はその1つを読んだしかし、私が探している部分は、リポジトリの外部でデータベースコンテキストを作成する方法を助けます。 – madvora

答えて

5

すでにコントロールフレームワークの反転を使用しているように見えるので、次のようにReadRepositoryWriteRepositoryはクラスを更新:

ReadRepository

public class ReadRepository : IReadRepository 
{ 
    private MyDBEntities db; 

    public ReadRepository(MyDBEntities myDbEntities) 
    { 
     db = myDbEntities; 
    } 

    //Provides the record to the write repository to edit 
    public MyTable GetRecord(int ID) 
    { 
     var record = (from t in db.MyTable 
         where t.ID == ID 
         select t).SingleOrDefault(); 

     return record; 
    } 
} 

書き戻し

あなたはそれらのクラスのコンストラクタでその依存関係を指定し、コントロールフレームワークのあなたの反転は、それを作成する処理させる必要がありますので、どちらもあなたの ReadRepositoryWriteRepositoryは、仕事をする MyDBEntitiesのインスタンスに依存
public class WriteRepository : IWriteRepository 
{ 
    private MyDBEntities db; 
    private IReadRepository _readRepository; 

    public WriteRepository(MyDBEntities myDbEntities, IReadRepository readeadRepository) 
    { 
     db = myDbEntities; 
     _readRepository = readRepository; 
    }   

    public void EditRecord(MyViewModel model) 
    { 
     //Get the specific record to be updated 
     var record = readRepository.GetRecord(model.ID); 

     //Update the data 
     record.FirstName = model.Name; 

     //This isn't saving 
     db.SaveChanges(); 
    } 
} 

MyDBEntitiesの新しいインスタンスを作成するのではなく、

Inversion of Controlフレームワークの登録で、MyDBEntitiesインスタンスをスコープまたはリクエストごとに登録し、一時的ではないことを確認してください。各リクエストでReadRepositoryWriteRepositoryの2つのインスタンスではなく、MyDBEntitiesクラスの同じインスタンスが注入されていることを確認します。

次のようにUnityコンフィギュレーションを更新します。

UnityConfig.cs

を要求ごとのスコープにUnityでの自分のMyDBEntitiesクラスを登録します。

public class UnityConfig 
{ 
    // ... other methods ... 

    public static void RegisterTypes(IUnityContainer container) 
    { 
     // ... other registrations ... 
     container.RegisterType<IReadRepository, ReadRepository>(); 
     container.RegisterType<IWriteRepository, WriteRepository>(); 
     container.RegisterType<MyDBEntities>(new PerRequestLifetimeManager()); 
     // ... other registrations ... 
    } 
} 

UnityMvcActivator.cs

TODO下の行のコメントを外すことにより、ユニティにおける要求ごとのスコープを有効にします。

public static class UnityWebActivator 
{ 
    public static void Start() 
    { 
     // ... start code ... 
     // TODO: Uncomment if you want to use PerRequestLifetimeManager 
     Microsoft.Web.Infrastructure.DynamicModuleHelper.DynamicModuleUtility.RegisterModule(typeof(UnityPerRequestHttpModule)); 
    } 

    // ... other methods ... 
} 
+0

優れた答え。あなたは私が必要としているもので正しいです。私は実際にフレームワークのためにUnityを使用していますが、登録するものや最後の部分のエンティティを登録する方法を理解することはできません。 – madvora

+0

私はUnityの登録で自分の答えを更新しました。 –

+0

更新いただきありがとうございます。私はこれを試して、すべてがうまくいくならば答えとしてマークします。 – madvora

関連する問題