我得到一个错误跟踪相同的模型,但我不知道如何访问模型和保存更改。错误是这样的:
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
以知道它是否正在创建新的元数据,但我相信在那个时候,元数据可能已经被创建(在其他地方)。然而,这是我们在这种情况下处理它的一般逻辑(比如只有在没有现有数据时才添加实体,否则更新所获取和跟踪的实体的属性)。