将多对多关系从 ApplicationUser 添加到自定义实体 [英] Adding Many to Many relationship from ApplicationUser to custom entity

查看:15
本文介绍了将多对多关系从 ApplicationUser 添加到自定义实体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在 EF 6.1 中设置从 ASP.NET Identity 中的用户实体 (ApplicationUser) 到自定义实体 (Group) 的多对多关系.我将 Code First 和 Migrations 与带有 ASP.Net Identity 的股票标准 MVC 示例应用程序一起使用.运行 Update-Database 似乎效果很好,因为我最终得到了所有 AspNet* 表以及我的实体和链接表:

I'm trying to setup a many to many relationship in EF 6.1 from the User entity (ApplicationUser) in ASP.NET Identity to a custom entity (Group). I'm using Code First and Migrations with the stock standard MVC sample app with ASP.Net Identity. Running Update-Database seems to work nicely as I end up with all the AspNet* tables plus my entity and a linking table:

群组
GroupAspNetUsers

我的 ApplicationUser 声明有一个 Group 集合,同样我的 Group 有一个 ApplicationUser 集合:

My ApplicationUser declaration has a collection of Group, and likewise my Group has a collection of ApplicationUser:

public class ApplicationUser : IdentityUser
{
    public virtual ICollection<Group> Groups { get; set; }

我可以创建用户和组,但对于我来说,我不知道如何链接它们.我本来希望这样的事情能奏效:

I can create users and groups, but for the life of me I can't work out how to link them. I would have expected something like this to work:

Group group = Context.Groups.Single(g => g.Id == 1);
var user = new ApplicationUser() { UserName = model.Email, Email = model.Email };
IdentityResult result = await UserManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
    // link this user to a group
    group.ApplicationUsers.Add(user);
    Context.SaveChanges();

但是,当我运行上面的代码时,我得到一个 DbEntityValidationException 说明用户名已被占用.

However when I run the code above, I get a DbEntityValidationException stating the user name is already taken.

我已经尝试加载 2 个自定义实体并以这种方式链接它们,在链接表中插入一条记录没有问题.

I've tried loading 2 custom entities and linking them in this way, which inserts a record into the linking table no problem.

因此,关于 ApplicationUser 的不同之处,我不了解.

So there is something I don't follow about how ApplicationUser is different.

我的自定义实体和 ASP.Net 身份实体应该使用相同的数据库上下文,因为我的所有控制器都从基本控制器继承.

My custom entities and the ASP.Net Identity entities should be using the same DB context as all my controllers inherit from a base controller.

更新:
我也尝试过从另一种方式来解决这个问题(向用户添加一个组),但没有任何运气:

UPDATE:
I've also tried approaching this from the other way around (add a group to a user), without any luck:

IdentityResult result = await UserManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
    // attempting to add group to a user
    user.Groups.Add(group);
    Context.SaveChanges();    

此代码运行时不会引发错误,但它不会向我的 GroupAspNetUsers 表添加记录.

This code runs without throwing an error, however it doesn't add a record to my GroupAspNetUsers table though.

我的下一步是尝试创建一个单独的实体(例如 UserInfo),它与 ApplicationUser 具有 1 对 1 的映射关系.然后我应该能够设置从 UserInfo 到 Group 的多对多.

My next step is to try creating a separate entity (eg. UserInfo) which has a 1 to 1 mapping with ApplicationUser. Then I should be able to setup a many to many from UserInfo to Group.

解决方案

双重插入问题源于 UserManager.CreateAsync 调用,它将在不同的线程上创建用户.当前线程不知道这一点,然后尝试再次插入用户.

The double insert problem stems from the UserManager.CreateAsync call, which will create the user on a different thread. The current thread, being unaware of this, then tries to insert the user again.

将方法更改为 UserMannager.Create 解决了问题,但正如 @Horizo​​n_Net 指出的那样,混合身份和上下文方法还有其他问题(我遇到过).

Changing the method to UserMannager.Create solved the problem, however as @Horizon_Net pointed out there are other issues with mixing identity and context methods (which I ran into).

解决方案是创建用户,然后重定向到另一个控制器以将用户链接到组.这很顺利.

The solution was to create the user, then redirect off to another controller to link the user to a group. This worked without a hitch.

推荐答案

问题不是来自您的群组集合.以下两行是问题

The problem does not come from your groups collection. The following two lines are the problem

IdentityResult result = await UserManager.CreateAsync(user, model.Password);
...
Context.SaveChanges();

幕后发生的事情是,在第一次调用时创建了一个用户.通过第二次调用,它再次尝试插入该用户.这就是您收到此错误消息的原因.

What happens behind the scenes is that with the first call a user is created. With the second call it again tries to insert this user. That's the reason why you get this error message.

一般来说,您应该避免混合 Identity 为您提供的方法和处理上下文本身.这可能会产生很多副作用(例如您的示例).

In general, you should avoid to mix the methods Identity gives you and working on the context itself. This can have a lot of side effects (like in your example).

参考看看这个线程

这篇关于将多对多关系从 ApplicationUser 添加到自定义实体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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