如何在实体框架模型中引用用户对象?
我有以下模型:
public class MyEntity
{
public Guid Id { get; set; }
public virtual ICollection<ApplicationUser> AssociatedUsers { get; set; }
public MyEntity()
{
AssociatedUsers = new HashSet<ApplicationUser>();
}
}
请注意,每个实体都有一些关联的用户.在我的控制器中,我试图像这样将 MyEntity
的实例添加到数据库中:
Notice that each entity has some associated users. In my controller, I'm trying to add an instance of MyEntity
to the database like this:
private ApplicationDbContext db = new ApplicationDbContext();
// ...
ApplicationUser currentUser = System.Web.HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>().FindById(System.Web.HttpContext.Current.User.Identity.GetUserId());
MyEntity entityInstance = new MyEntity();
entityInstance.Id = Guid.NewGuid();
entityInstance.AssociatedUsers.Add(currentUser);
db.MyEntities.Add(entityInstance);
db.SaveChanges();
但是,该代码引发以下错误:
However, that code throws the following error:
IEntityChangeTracker的多个实例不能引用一个实体对象.
An entity object cannot be referenced by multiple instances of IEntityChangeTracker.
我从该错误消息中收集到 CurrentUser
仍由数据库上下文管理,该上下文支持 ApplicationUserManager
,因此无法将其添加到其他上下文中.但与我发现的其他案例不同,href ="https://stackoverflow.com/questions/10191734/entity-object-cannot-be-referenced by-multiple-instances-of-ientitychangetracker">>,我不能简单地切换上下文以便它们共享数据库连接:用户对象来自 ApplicationUserManager
.我需要怎么做才能解决这个问题?我是从根本上做错了吗?我知道我可以改用ID并查找相应的用户,但我希望直接访问该对象.
I gather from that error message that CurrentUser
is still being managed by the database context which backs the ApplicationUserManager
, so I can't add it to a different context. But unlike other cases that I have found documented, I can't simply switch the context so that they share a database connection: the user object is coming from an ApplicationUserManager
. What do I need to do to resolve this? Am I doing something fundamentally wrong? I am aware that I could use the ID instead and look up the corresponding user, but I would rather have the object accessible directly.
您的问题与您发布的链接中的问题非常相似.简而言之,您无法在不同的上下文中操纵用户.在这里:
Your problem is very similar to the problem found in the link you've posted. In a few words, you can't manipulate a user from different contexts. Here:
ApplicationUser currentUser = System.Web.HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>().FindById(System.Web.HttpContext.Current.User.Identity.GetUserId());
您实际上是从 System.Web.HttpContext.Current.GetOwinContext()
中获取了 currentUser
,但是随后您尝试使用 db
code>,它是 ApplicationDbContext
.
You effectively got currentUser
from System.Web.HttpContext.Current.GetOwinContext()
, but then you're trying to save it using db
, which is an ApplicationDbContext
.
将其保留在相同的上下文中,您将可以解决问题:
Keep it on the same context, and you will have your problem solved:
var currentUser = db.Users.Find(System.Web.HttpContext.Current.User.Identity.GetUserId());
var entityInstance = new MyEntity();
entityInstance.Id = Guid.NewGuid();
entityInstance.AssociatedUsers.Add(currentUser);
db.MyEntities.Add(entityInstance);
db.SaveChanges();