问题描述
这是 MVC 5/EF6.所以我有以下课程:
This is MVC 5/ EF6. So I have the following classes:
public class User : IdentityUser
{
public User()
{
Levels = new List<Level>();
}
[Required, MaxLength(200)]
public string FirstName { get; set; }
[Required, MaxLength(200)]
public string LastName { get; set; }
public virtual ICollection<Level> Levels { get; set; }
}
和
public class Level
{
public int Id { get; set; }
[Required]
public string Name { get; set; }
public virtual ICollection<User> Users { get; set; }
}
除了常规的 MVC5 成员表之外,它还创建了 2 个:Levels
和 UserLevels
(带有 User_Id 和 Level_Id 列).Levels
表有一个静态数据(即 1 - 优秀,2 - 好等)并且是一种库,我不想插入到这个表中.
In addition to regular MVC5 membership tables it creates 2 more: Levels
and UserLevels
(with User_Id and Level_Id columns). Levels
table has a static data (i.e. 1 - Excellent, 2 - Good, etc) and is kind of a library, I don't want to insert in this table.
我想要做的是当用户在网站上注册并选择它会继续并从数据库中检索它的级别时,以便 UserLevels
表填充新的 UserID
并选择 LevelID
.这是我的代码:
What I'm trying to do is when user registers on the site and chooses the level it would go ahead and retrieve it from DB so that UserLevels
table is populated with new UserID
and selected LevelID
. Here is my code:
Level level = DBContext.Levels.Where(s => s.Name == model.Level.Name).SingleOrDefault();
if (level == null)
ModelState.AddModelError("", "Invalid Level.");
if (ModelState.IsValid)
{
var user = new User() {
UserName = model.UserName,
FirstName = model.FirstName,
LastName = model.LastName
};
user.Levels.Add(level);
var result = await UserManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
await SignInAsync(user, isPersistent: false);
return RedirectToAction("Index", "Home");
}
else
{
AddErrors(result);
}
}
return View(model);
在这一行抛出异常:一个实体对象不能被多个IEntityChangeTracker实例引用..
var result = await UserManager.CreateAsync(user, model.Password);
我猜这与尝试将其中已经存在的关卡插入 Levels 表有关吗?当然它可能是别的东西......有什么建议吗?提前致谢!
I'm guessing it has something to do with it trying to insert into Levels table the level that already exists in there? Of course it might be something else... Any advice? Thanks in advance!
推荐答案
如果您以开箱即用"的方式使用 UserManager
,那么它可能会像这样实例化:
If you're using UserManager
the way 'it came out of the box' then it's probably instantiated like this:
public AccountController()
: this(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new MyDbContext())))
{
}
public AccountController(UserManager<ApplicationUser> userManager)
{
UserManager = userManager;
}
public UserManager<ApplicationUser> UserManager { get; private set; }
这意味着如果你不向 AccountController
构造函数提供一个 UserManager
实例(这里可能就是这种情况),一个新的 MyDbContext
是为 UserManager
存储创建的.
It means that if you don't provide a UserManager
instance to the AccountController
constructor (and it's probably the case here), a new MyDbContext
is created for the UserManager
store.
然而,您有另一个 MyDbContext
实例,我可以从您的代码中的这一行推断:
Yet, you have another instance of MyDbContext
, as i can infer from this line in your code:
Level level = DBContext.Levels.Where(s => s.Name == model.Level.Name).SingleOrDefault();
这意味着你必须让你的 UserManager
使用相同的上下文:
All it means is that you have to make your UserManager
use the same context:
public AccountController() : this(null)
{
}
public AccountController(UserManager<User> userManager = null)
{
DBContext = new MyDBContext();
if (userManager == null)
userManager = new UserManager<User>(new UserStore<User>(DBContext));
UserManager = userManager;
}
public UserManager<User> UserManager { get; private set; }
public MyDBContext DBContext;
这样,您首先创建(唯一的)MyDbContext
实例,然后将其传递给 UserManager
构造函数(作为 IUserStore
).
This way, you're creating the (only) MyDbContext
instance first, then passing it to the UserManager
constructor (as the IUserStore<User>
).
此外,您绝对可以在此处充分利用依赖注入,并通过 DI 容器为您注入 MyDbContext
实例并保持当前代码几乎不变:
Also, you can definitely make a good use of Dependency Injection here and have the MyDbContext
instance injected for you by a DI container and keeping your current code almost unchanged:
public AccountController(MyDBContext context)
: this(new UserManager<User>(new UserStore<User>(context)))
{
this.DBContext = context;
}
请参阅 教程(适用于 Microsoft Unity).
See Tutorial (for Microsoft Unity).
这篇关于Entity Framework 6 和 Asp.Net Identity UserManager:多个 DbContext的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!