【问题标题】:Null Exception on EntityState.Detached in Asp.Net Core 5.0 [closed]Asp.Net Core 5.0 中 EntityState.Detached 的空异常 [关闭]
【发布时间】:2021-10-01 06:22:20
【问题描述】:

我有一个用户个人资料页面,用户可以更新它自己的信息。 当我尝试更新时,我收到instance of entity type cannot be tracked because another instance with same key value is tracked 错误,我已经四处寻找解决这个问题。我知道我需要将该对象指向Detached,这样我就可以更新它而不会在Try-Catch 块中出现任何错误。让我先向您展示我的前端和后端。 前端:

<form class="mt-0" asp-action="MyProfile" enctype="multipart/form-data" method="post">
    <input asp-for="User.UserID" type="hidden" value="@Model.User.UserID" name="UserID">
    <input asp-for="User.UserPassword" type="hidden" value="@Model.User.UserPassword" name="UserPassword">
    <input asp-for="User.UserEMail" type="hidden" value="@Model.User.UserEMail" name="UserEMail">
    <input asp-for="User.UserToken" type="hidden" value="@Model.User.UserToken" name="UserToken">
    <input asp-for="User.UserRequestToken" type="hidden" value="@Model.User.UserRequestToken" name="UserRequestToken">
    <input asp-for="User.UserIsActive" type="hidden" value="@Model.User.UserIsActive" name="UserIsActive">
    <input asp-for="User.UserIsEmailConfirmed" type="hidden" value="@Model.User.UserIsEmailConfirmed" name="UserIsEmailConfirmed">
    <input asp-for="User.CompanyID" type="hidden" value="@Model.User.CompanyID" name="CompanyID">
    <input asp-for="User.UserRoleID" type="hidden" value="@Model.User.UserRoleID" name="UserRoleID">
    <input asp-for="User.CompanyIsAdmin" type="hidden" value="@Model.User.CompanyIsAdmin" name="CompanyIsAdmin">
    <input asp-for="User.CreatedDate" type="hidden" value="@Model.User.CreatedDate" name="CreatedDate">
    <div class="form-row mb-4">
        <div class="col">
            <label asp-for="User.UserName"><b>Kullanıcı Adı</b></label>
            <input asp-for="User.UserName" type="text" class="form-control"
                   placeholder="Ad" name="UserName" value="@Model.User.UserName" required>
            <span asp-validation-for="User.UserName" class="text-danger"></span>
        </div>
        <div class="col">
            <label asp-for="User.UserSurname"><b>Kullanıcı Soyadı</b></label>
            <input asp-for="User.UserSurname" type="text" class="form-control"
                   placeholder="Soyad" name="UserSurname" value="@Model.User.UserSurname" required>
            <span asp-validation-for="User.UserSurname" class="text-danger"></span>
        </div>
    </div>
    <div class="form-row mb-4">
        <div class="col">
            <label asp-for="User.UserPhone"><b>Kullanıcı Telefonu</b></label>
            <input asp-for="User.UserPhone" type="text" class="form-control"
                  placeholder="+905555555555" minlength="11" name="UserPhone" value="@Model.User.UserPhone" required>
            <span asp-validation-for="User.UserPhone" class="text-danger"></span>
        </div>
        <div class="col">
            <label asp-for="User.UserBPhone"><b>Kullanıcı İş Telefonu</b></label>
            <input asp-for="User.UserBPhone" type="text" class="form-control"
                  placeholder="+905555555555" minlength="11" name="UserBPhone" value="@Model.User.UserBPhone">
            <span asp-validation-for="User.UserBPhone" class="text-danger"></span>
        </div>
    </div>
    <button type="submit" name="MyProfile" class="btn btn-primary mt-2 mb-2 btn-block">
        Update Your Informations
    </button>
</form>

后端:

#region /*UpdateMyProfile*/
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> MyProfile(User user)
{
    try
    {
        if (ModelState.IsValid)
        {
            // That's the point where i got the null exception error
           _context.Entry(user).State =Microsoft.EntityFrameworkCore.EntityState.Detached;
            // That's the point where i got the null exception error
            user.ModifiedDate = DateTime.Now;
            user.ModifiedUserId = getCurrentUser();
            user.ModifiedUserType = getCurrentUserClaimRole();
            await _unitOfWorkUser.RepositoryUser.UpdateAsync(user);
            await _unitOfWorkUser.CompleteAsync();
            var log = _logging.Logging("Firma (Kullanıcı Bilgilerini) Güncelledi", "Update/Post",//
            user.UserID.ToString(), "Company-MyProfile/UpdateMyProfile", getCurrentUser(), getCurrentUserClaimRole());
            await _unitOfWorkLog.RepositoryLog.CreateAsync(log);
            await _unitOfWorkLog.CompleteAsync();
            return RedirectToAction("MyProfile");
        }
        else
        {
            TempData["Message"] = "İşleminiz Başarısız.";
            TempData["JS"] = "showError();";
            return RedirectToAction("MyProfile");
        }
    }
    catch (Exception ex)
    {
        var log = _logging.Logging(ex.Message, "Exception/Hata", user.UserID.ToString(),
           "MyProfile/UpdateMyProfile", getCurrentUser(), getCurrentUserClaimRole());
        _unitOfWorkLog.RepositoryLog.Create(log);
        _unitOfWorkLog.Complete();
        TempData["Message"] = ex.Message;
        TempData["JS"] = "showError();";
        return RedirectToAction("MyProfile");
    }
}

我将异常指向后端方法。我不知道为什么,但是当我尝试Detached 对象时,我得到了 Null Exception。我不知道为什么我会收到这个错误,我的意思是它没有意义。

【问题讨论】:

  • 我们在这里看到零 EF 代码。另外,您是否检查过user 不是null?您应该调试自己的代码并告诉实际为 null 的内容。我们无法为您做到这一点。
  • 用户不为空。我确定这一点,我已经看过相关的对象。我相信它不是空异常错误。当我弄清楚时我会告诉你的

标签: c# asp.net-mvc asp.net-core .net-core entity-framework-core


【解决方案1】:

我一直认为使用 UoW 和通用存储库绝不是一个好主意(例如阅读 https://gunnarpeipman.com/ef-core-repository-unit-of-work/ )所以这是我将使用的代码。如果可以或需要,您可以将其修改为 UoW

    var userExisted=_context.Set<User>().FirstOrDefault(Id==user.Id);
     if (userExisted==null) ....exception error

     _context.Entry(userExisted).CurrentValues.SetValues(user);
                
            userExisted.ModifiedDate = DateTime.Now;
            userExisted.ModifiedUserId = getCurrentUser();
            userExisted.ModifiedUserType = getCurrentUserClaimRole();

           var result = await _context.SaveChangesAsync();

           if(result==0) ...error
          

【讨论】:

  • 有ID实现对吗?我没有那个实现,我真的不知道该怎么做。你能建议我一个示例 github repo 或一些链接吗,因为我已经在搜索它但我找不到它。 @Serge
  • @BerkGarip 抱歉,ID 实现是什么意思?
  • 我解决了它,你启发了我一些方法。非常感谢先生
【解决方案2】:

像这样更新你的后端代码:-

//clarify code

   if (!user.IsNull())
    {
        _context.Entry(user).State =Microsoft.EntityFrameworkCore.EntityState.Detached;
    }

//clarify code

更新

首先,您必须为您的User 模型创建一个ViewModel。 假设您的 ViewModel 名称是 UserVM

现在更新您的代码,如下所示:-

 try
    {
        if (ModelState.IsValid)
        {
          UserVm user1= new UserVm()
                {
                    UserName = user.UserName,
                    UserPhone= user.UserPhone,
                    
                    //and so on as needed.
                };
    if (!user1.IsNull())
    {
         _context.Entry(user1).State =Microsoft.EntityFrameworkCore.EntityState.Detached;
    }
//clarify code
       

试试吧,应该可以的。

【讨论】:

  • 你可以看到我使用if (ModelState.IsValid) 并且你不能像在后端那样控制它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-17
  • 2021-02-26
  • 2020-01-12
  • 1970-01-01
相关资源
最近更新 更多