将实体添加到上下文时,“IEntityChangeTracker 的多个实例不能引用实体对象”
本文关键字:实体 实例 不能 引用 对象 IEntityChangeTracker 添加 上下文 | 更新日期: 2023-09-27 18:32:27
我正在编写一个包含几个多对多关联的 MVC 应用程序。其中之一是自定义Role <---> Account
关联。基本上,我有一个充满预定义角色的表格,用户可以从中进行选择。我创建了一个 ViewModel,其中包含我的实体模型和我使用的一些集合,其中一个集合是 Roles 集合。然后,我使用这些值填充我的"创建"窗体,并在[HttpPost]
"创建"操作中再次解析它们。
以下是相关代码:
视图模型类:
public class AccountsViewModel
{
public Accounts Account { get; set; }
public List<Roles> RolesList { get; set; }
}
控制器代码:
public ActionResult Create()
{
AccountsViewModel viewModel = new AccountsViewModel();
viewModel.RolesList = rolesService.GetAllRoles();
return View(viewModel);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(AccountsViewModel viewModel)
{
if (ModelState.IsValid)
{
foreach(Roles role in viewModel.RolesList)
{
if (role.IsSelected)
{
Roles selectedRole = rolesService.GetRole(role.Id);
viewModel.Account.Roles.Add(selectedRole);
}
}
//Some more code here...
accountsService.AddAccount(viewModel.Account);
}
}
定制服务类 ( accountsService
)
public void AddAccount(Accounts newAccount)
{
//AppDataContext is an instance of <Model>Container
AppDataContext.AccountsSet.Add(newAccount);
AppDataContext.SaveChanges();
}
和我的创建视图:
<div class="form-group">
@Html.LabelFor(model => model.Account.Roles, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@for (int i = 0; i < Model.RolesList.Count; i++)
{
@Html.HiddenFor(m => m.RolesList[i].Id)
@Html.CheckBoxFor(m => m.RolesList[i].IsSelected)
@Html.LabelFor(m => m.RolesList[i].IsSelected, Model.RolesList[i].Name)
<br />
}
</div>
</div>
现在到我的实际问题,每次我尝试添加新的 Accounts 对象时,我都会收到一个错误,"An entity object cannot be referenced by multiple instances of IEntityChangeTracker."
我已经查看了在互联网上找到的一些帖子,但我无法真正将它们与我在代码中犯的任何可能错误联系起来。那么有人可以在这里帮助我吗?
问题是newAccount
的角色仍然附加到roleService
的上下文中。一个实体一次只能附加到一个上下文。
您可以调用context.Entity(...).Detach()
来分离实体,甚至可以更好地在禁用更改跟踪且无需创建代理的情况下获取角色,因为这将为您提供巨大的速度提升:
context.Configuration.AutoDetectChangesEnabled = false;
context.Configuration.ProxyCreationEnabled = false;
最好在 using 块内创建一个新的上下文rolesService.GetRole(...)
这样您的上下文就不会随着时间的推移而受到污染(和缓慢)。