フレームワークで並行性を管理する必要がありますが、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)
その更新プログラムによって生成されるsqlを確認してください(context.Database.Log = ...) – Evk
ビューに '@Html.HiddenFor(m => m.RowVersion)'のようなものがありますか? (私はオートマトンを知らない)だから、もしあなたがセーブすれば、それはあなたが前にロードしたのと同じrowversionですか? –
はい、私は私のビューに隠れた入力 'RowVersion'を持っています。 'SaveChange'の直前で、オブジェクトの値はデータベースの値とは異なりますが、更新は機能します... –