1

フレームワークで並行性を管理する必要がありますが、DbUpdateConcurrencyExceptionを生成できません。私たちは使用してSQL Server 2008、EF 6とAutoMapper 5.同時実行アクセス、EntityFramework 6でDbUpdateConcurrencyExceptionが生成されないのはなぜですか?

SQL

ALTER TABLE [Keyword].[Keyword] ADD Rowversion [Rowversion] NOT NULL 

モデル

[Table("Keyword", Schema = "Mailing")] 
public class KeywordModel : _Auditable 
{ 
    [Key] 
    public int KeywordId { get; set; } 

    public string Name { get; set; } 
    public string Hashtag { get; set; } 
    public string Namespaces { get; set; } 
    public string Html { get; set; } 

    [Timestamp] 
    [ConcurrencyCheck] 
    public virtual byte[] RowVersion { get; set; } 
} 

のViewModel

public class KeywordEditViewModel 
{ 
    [HiddenInput(DisplayValue = false)] 
    public int KeywordId { get; set; } 

    [Display(Name = "Name")] 
    public string Name { get; set; } 

    [Display(Name = "Hashtag")] 
    public string Hashtag { get; set; } 

    [Display(Name = "Namespaces")] 
    [Description("Separate namespaces by ','")] 
    public string Namespaces { get; set; } 

    [Required] 
    [AllowHtml] 
    [UIHint("MultilineText")] 
    [Display(Name = "Html")] 
    [Description("Prefix or sufix your razor variables with #")] 
    public string Html { get; set; } 

    [Timestamp] 
    [ConcurrencyCheck] 
    public byte[] RowVersion { get; set; } 
} 

コントローラ

[HttpPost] 
    public virtual ActionResult Edit(KeywordEditViewModel model, string @return) 
    { 
     var data = new JsonResultData(ModelState); 

     if (ModelState.IsValid) 
     { 
      data.RunWithTry((resultData) => 
      { 
       KeywordManager.Update(model.KeywordId, model, CurrentUser.UserId); 
       resultData.RedirectUrl = !string.IsNullOrEmpty(@return) ? @return : Url.Action("Index"); 
      }); 
     } 

     return Json(data); 
    } 
私のテストでは

ビジネス

public KeywordModel Update(int id, object viewmodel, int userId) 
    { 
     var model = Get(id); 

     Mapper.Map(viewmodel, model); 
     SaveChanges("Update mailing keyword", userId); 

     return model; 
    } 

AutoMapper

CreateMap<KeywordModel, KeywordEditViewModel>(); 
CreateMap<KeywordEditViewModel, KeywordModel>(); 

、RowVersionフィールドは、データベース内の異なる値を持っていますが、SaveChangeは例外DbUpdateConcurrencyExceptionを生成しません。決して...

より良い後半

SQLトレース

UPDATE [Mailing].[Keyword] 
SET [Namespaces] = @0, [audit_LastUpdate] = @1 
WHERE (([KeywordId] = @2) AND ([RowVersion] = @3)) 
SELECT [RowVersion] 
FROM [Mailing].[Keyword] 
WHERE @@ROWCOUNT > 0 AND [KeywordId] = @2 
@0: 'titi' (Type = String, Size = -1) 
@1: '09/11/2016 13:35:54' (Type = DateTime2) 
@2: '1' (Type = Int32) 
@3: 'System.Byte[]' (Type = Binary, Size = 8) 
+0

その更新プログラムによって生成されるsqlを確認してください(context.Database.Log = ...) – Evk

+0

ビューに '@Html.HiddenFor(m => m.RowVersion)'のようなものがありますか? (私はオートマトンを知らない)だから、もしあなたがセーブすれば、それはあなたが前にロードしたのと同じrowversionですか? –

+0

はい、私は私のビューに隠れた入力 'RowVersion'を持っています。 'SaveChange'の直前で、オブジェクトの値はデータベースの値とは異なりますが、更新は機能します... –

答えて

0

私はこの正確なシナリオを探して数時間後に、この問題を解決しました。 EF、automapper、viewmodels、全体の9。数十の記事の後、誰かがついに私に正しい方向性と実際にはかなり単純な修正をもたらした何かを語った。

この呼び出しを行うと、次のようになります。var model = Get(id); 現在の値を取得し、更新を上にマップするには、新しい行バージョンが選択されます。

"Get(id)"をトラッキングなしで選択するように修正しました。問題が解決しました。私の場合、私のレポには、オブジェクトを変更済みとしてマークし、デタッチされている場合は添付された「編集(エンティティ)」メソッドがありました。ここでも同じことができるかもしれません。

関連する問題