C# 并发访问,为什么EntityFramework 6不生成DbUpdateConcurrencyException?

C# 并发访问,为什么EntityFramework 6不生成DbUpdateConcurrencyException?,c#,asp.net-mvc,model-view-controller,entity-framework-6,automapper-5,C#,Asp.net Mvc,Model View Controller,Entity Framework 6,Automapper 5,我必须在我们的框架中管理并发性,但我不能生成DbUpdateConcurrencyException。我们使用SQLServer2008、EF6和Automapper5 SQL 模型 视图模型 public class KeywordEditViewModel { [HiddenInput(DisplayValue = false)] public int KeywordId { get; set; } [Display(Name = "Name")] publ

我必须在我们的框架中管理并发性,但我不能生成DbUpdateConcurrencyException。我们使用SQLServer2008、EF6和Automapper5

SQL

模型

视图模型

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;
    }
汽车制造商

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

迟做总比不做好

经过几个小时的搜索,我解决了这个问题。EF,automapper,viewmodels,全部九个。在写了几十篇文章之后,终于有人说了一些话,引导我找到了正确的方向,这实际上是一个相当简单的解决方法

进行此调用时:var model=Get(id); 要获取当前值,然后将更新映射到顶部,将选择新行版本


修复方法是在不跟踪的情况下选择“获取(id)”。问题已解决。在我的例子中,我的repo有一个“编辑(实体)”的方法,该方法将对象标记为已修改,并在分离时附加它。您可以在此处执行同样的操作。

检查该更新生成的sql(context.Database.Log=…)您的视图中有类似于
@Html.HiddenFor(m=>m.RowVersion)
?(我不知道automapper)所以如果保存,它与以前加载的行版本相同?是的,我的视图中有一个隐藏的输入“rowversion”。就在“SaveChange”之前,“我的对象”中的值与数据库值不同,但更新有效。。。
    public KeywordModel Update(int id, object viewmodel, int userId)
    {
        var model = Get(id);

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

        return model;
    }
CreateMap<KeywordModel, KeywordEditViewModel>();
CreateMap<KeywordEditViewModel, KeywordModel>();
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)