2016-12-16 9 views
1

UserRolesテーブルを更新しようとしていますが、更新されません。私は2つのことを更新しようとしている:1.電子メール2.ユーザーの役割。更新は2つのテーブルで行う必要があるため、2つの別々のコマンドを使用しています。私は電子メール(ユーザー)だけで更新プログラムを実行すると、それは動作しますが、私はロール(AspUserRoles)を更新しても何もしません。 UserRoles.Attach(userRole)が更新を妨げているため、どちらも動作しません。私もエラーはありません。.Attach()で更新できません。

ApplicationRole.IdとApplicationUser.Idに値があるかどうかを確認して、必要な値を返します。ここで

enter image description here

は私UserController.csです:あなたは、このコード内のデータを変更している

public async Task<IActionResult> Edit(UserViewModel model, Guid id) 
{ 
    var alert = new Alert(); 

    try 
    { 
     if(!ModelState.IsValid) 
     { 
      alert.Message = alert.ExceptionMessage = ApplicationDbContextMessage.INVALID; 
      throw new Exception(); 
     }  


     var originalModel = ApplicationDbContext.Users.FirstOrDefault(u => u.Id == id);  
     var userRole = ApplicationDbContext.UserRoles.FirstOrDefault(i => i.UserId == id); 


     if(originalModel == null) 
     { 
      alert.Message = alert.ExceptionMessage = ApplicationDbContextMessage.NOTEXISTS; 
      throw new Exception(); 

     } 


     originalModel.Email = model.ApplicationUser.Email; 

     userRole.RoleId = model.ApplicationRole.Id; 


     ApplicationDbContext.Users.Attach(originalModel); 
     ApplicationDbContext.UserRoles.Attach(userRole); 


     ApplicationDbContext.Entry(originalModel).State = EntityState.Modified; 


     if (await ApplicationDbContext.SaveChangesAsync() == 0) 
     { 
      alert.Message = alert.ExceptionMessage = ApplicationDbContextMessage.EDITNOK; 
      throw new Exception(); 
     } 

     alert.Message = ApplicationDbContextMessage.EDITOK; 
     return RedirectToAction("Index"); 
    } 
    catch(Exception ex) 
    { 
     alert.Type = AlertType.Error; 
     alert.ExceptionMessage = ex.Message; 

     model = await ViewModel(model.ApplicationUser); 

     ModelState.AddModelError(string.Empty, alert.ExceptionMessage); 
    } 
    return View(model); 
} 
+1

これらのオブジェクトに「Attach」を呼び出す必要はありません。保存されているのと同じコンテキストから来ており、切断されることはありません。あなたは 'Attach'を呼ぶか、' EntityState'をつぶすことなしにこれを試しましたか? –

+0

私はやったし、動作しません。 Attach(userRole)の代わりにAdd(userRole)を実行すると、UserRoleテーブルに新しい行が追加されますが、同じUserIdを持つdublicateがあります。 – hxwtch

+0

'Add 'を呼び出す必要はありません。プロパティを変更し、コンテキスト上で 'SaveChanges'を呼び出してください。あなたは元の投稿されたコードを取り、 'Attach'と言う2行と' State'を変更する行を削除して動作させることができます。 –

答えて

2

方法、あなたはそれが知らせるためにContextAttachAddを呼び出す必要はありませんエンティティへの変更は自動的に行われます。

DbContextDbSetからエンティティを取得した瞬間から、それはDbContextによって追跡(添付)されています。 DbContextSaveChangesを呼び出すと、現在の値と古い値を比較して、変更を検出するすべてのエンティティをスキャンします。これらの変更はデータベースに送信されます。

文字通り、最初に投稿したコードから3行のコードを削除して機能させる必要があります。

... 
originalModel.Email = model.ApplicationUser.Email; 
userRole.RoleId = model.ApplicationRole.Id; 

ApplicationDbContext.Users.Attach(originalModel); // <--- Delete this line 
ApplicationDbContext.UserRoles.Attach(userRole); // <--- Delete this line 
ApplicationDbContext.Entry(originalModel).State = EntityState.Modified; // <--- Delete this line 

if (await ApplicationDbContext.SaveChangesAsync() == 0) 
... 

私は気づいた他の少し何か。アプリケーション全体に対して単一のDbContextインスタンスを使用しているようです。これは、通常、Entity Frameworkの「Anti-Patern」とみなされます。実行する「論理」操作ごとに新しいDbContextインスタンス(using)を作成する必要があります。そのインスタンスは、その操作の存続期間中にのみ生きていなければなりません。

MVCでは、通常のインスタンスがActionMethodになります。

関連する問題