异常实体已经被跟踪



我得到一个错误跟踪相同的模型,但我不知道如何访问模型和保存更改。错误是这样的:

System.InvalidOperationException: 'The instance of entity type 'UserMetaData' cannot be tracked 
because another instance with the same key value for {'UserId'} is already being tracked. When attaching
existing entities, ensure that only one entity instance with a given key value is attached. Consider 
using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see the conflicting key values.'

导致我的网站崩溃的代码是:

public IActionResult ConsentForm(string holder)
{
var id = _httpContextAccessor.HttpContext.Session.GetString("UserId");
var userId = new Guid(id);
var userMetaInfo = _elearnContext.UserMetaData.Where(u => u.UserId == userId).SingleOrDefault();

UserMetaData userMetaData = new UserMetaData
{
UserId = userId,
Consent = userMetaInfo.Consent,
Location = "",
CanChangePassword = true
};
_elearnContext.UserMetaData.Add(userMetaData);// crashes here 
_elearnContext.SaveChanges();
return RedirectToAction("LogOn", "Account");
// return View("~/Views/Home/ConsentForm.cshtml", ConsentData);
}

我认为问题是,在我调用这个函数之前,我在前一个函数中使用了相同的访问权限,像这样:

public IActionResult RedirectToConsentForm(string controllerName, string actionName)
{
var Id = _httpContextAccessor.HttpContext.Session.GetString("UserId");
var UserId = new Guid(Id);
var UserMetaInfo = _elearnContext.UserMetaData.Where(u => u.UserId == UserId).SingleOrDefault();

if (UserMetaInfo.Consent == true)
{
return RedirectToAction("ConsentForm", "Account");
}
else
{
return RedirectToAction(controllerName, actionName);
}
}

如果有人有什么想法,请告诉我。

在这种情况下,您的场景实际上是更新元数据(如果存在),否则添加一个新的元数据。它崩溃是因为在查询元数据之后,它被跟踪了(没有使用AsNoTracking)。然后,跟踪的实体被添加到上下文中并导致错误。它应该是这样的:

var userMetaInfo = _elearnContext.UserMetaData.SingleOrDefault(u => u.UserId == userId) ?? new UserMetaData();
if(userMetaInfo.UserId == 0){
//set the consent only at the time creating a new metadata
userMetaInfo.Location = someLocation;
userMetaInfo.CanChangePassword = true;
//add the new entity to the context (mark it as added)
_elearnContext.UserMetaData.Add(userMetaInfo);
}
//now set this to update the consent which should be true
//because this code is run only after the user accepted (redirected from another action)
userMetaInfo.Consent = true;
//finally save the changes
_elearnContext.SaveChanges();

注意我不确定您为Location设置了什么(以及何时更新它)。这取决于你的逻辑。但是看起来在上面的代码中,你唯一想要更新的是Consent属性,它必须是true。虽然我们检查UserId以知道它是否正在创建新的元数据,但我相信在那个时候,元数据可能已经被创建(在其他地方)。然而,这是我们在这种情况下处理它的一般逻辑(比如只有在没有现有数据时才添加实体,否则更新所获取和跟踪的实体的属性)。

相关内容

最新更新