实体框架6和Asp.Net的UserManager身份:多的DbContext [英] Entity Framework 6 and Asp.Net Identity UserManager: Multiple DbContext

查看:315
本文介绍了实体框架6和Asp.Net的UserManager身份:多的DbContext的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是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个:色阶 UserLevels (与USER_ID及Level_Id列)。 级别表中有一个静态数据(即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 表中填充新的用户名和选择 LevelID 。这里是我的code:

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的结果=等待UserManager.CreateAsync(用户,model.Password);

我猜它是与它试图插入级别表已经存在于那里的水平?当然,它可能是别的东西......有什么建议?在此先感谢!

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; }

这意味着,如果你不提供的UserManager 实例给的AccountController 的构造函数(和它可能是在此情况下),一个新的 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 的另一个实例,因为我可以从你的code此行推断:

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 使用相同的上下文:

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&lt;使用者&GT; )。

This way, you're creating the (only) MyDbContext instance first, then passing it to the UserManager constructor (as the IUserStore<User>).

另外,你绝对可以做一个良好的使用依赖注入这里有一个DI容器注入适合你的 MyDbContext 实例,并维持目前的code几乎不变的:

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;
}

请参阅教程(微软统一)

这篇关于实体框架6和Asp.Net的UserManager身份:多的DbContext的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆