同一班级的多对多关系不起作用

时间:2017-09-10 21:21:10

标签: c# many-to-many entity-framework-core

我正在尝试使用EFCore在同一个用户类上创建多对多关系,我基于EntityFrameworkCore.IdentityUser,遵循hereherehere所述的说明。我有以下用户类:

public class MyApplicationUser : IdentityUser
{
    public virtual ICollection<MyApplicationUserJunction> MyApplicationUsers { get; set; }
    public virtual ICollection<MyApplicationUserJunction> ManagingMyApplicationUsers { get; set; }
}

这是我的加入表:

public class MyApplicationUserJunction
{
    public int MyApplicationUserId { get; set; }
    public virtual MyApplicationUser MyApplicationUser { get; set; }
    public int ManagedMyApplicationUserId { get; set; }
    public virtual MyApplicationUser ManagedMyApplicationUser { get; set; }
}

这是我的OnModelConfiguring:

protected override void OnModelCreating(ModelBuilder builder)
{
    base.OnModelCreating(builder);

    builder.Entity<MyApplicationUserJunction>()
        .HasKey(uj => new { uj.ManagedMyApplicationUserId, uj.MyApplicationUserId});

    builder.Entity<MyApplicationUserJunction>()
        .HasOne(uj => uj.MyApplicationUser)
        .WithMany(qu => qu.MyApplicationUsers)
        .HasForeignKey(uj => uj.MyApplicationUserId).OnDelete(DeleteBehavior.Restrict);

    builder.Entity<MyApplicationUserJunction>()
        .HasOne(uj => uj.ManagedMyApplicationUser)
        .WithMany(qu => qu.ManagingMyApplicationUsers)
        .HasForeignKey(uj => uj.ManagedMyApplicationUserId);
}

每当我运行EFCore工具添加迁移命令时,我都会收到以下错误:

  

从“MyApplicationUserJunction.MyApplicationUser”到“M​​yApplicationUser.MyApplicationUsers”与外键属性{'MyApplicationUserId':int}之间的关系无法定位主键{'Id':string},因为它不兼容。为此关系配置主键或一组兼容的外键属性。

我正在使用EntityFrameworkCore.Tools.DotNet软件包1.0.0-preview3-final。

我只尝试在User类上使用单个导航属性,并且我没有像here所述那样指定WithMany函数,但没有成功。

1 个答案:

答案 0 :(得分:1)

为了使用EF Core 1,按照Rufo先生的建议,我指定了TKey的类型:

public class MyApplicationUser : IdentityUser<int>
{
    public virtual ICollection<MyApplicationUserJunction> MyApplicationUsers { get; set; }
    public virtual ICollection<MyApplicationUserJunction> ManagingMyApplicationUsers { get; set; }
}

并在上下文中:

public class MyApplicationContext : IdentityDbContext<MyApplicationUser, IdentityRole<int>, int>
{
    ...

并在ConfigureServices的AddIdentity部分中,它也使用通用IdentityRole:

services.AddIdentity<MyApplicationUser, IdentityRole<int>>(config =>
        {
            config.User.RequireUniqueEmail = true;
            config.Password.RequiredLength = 8;
            config.Cookies.ApplicationCookie.LoginPath = "/Auth/Login";
        })
        .AddEntityFrameworkStores<MyApplicationContext, int>();

然后我将其升级到EF Core 2,这需要进行一些其他更改才能使身份正常工作。正如pealmeid here所描述的那样,你必须从IdentityRole派生出来:

public class MyRole : IdentityRole<int>
{
    public MyRole() : base()
    {
    }

    public MyRole(string roleName)
    {
        Name = roleName;
    }
}

在ConfigureServices中使用:

public void ConfigureServices(IServiceCollection services)
        {
            services.AddIdentity<MyApplicationUser, MyRole>(config =>
            {
                config.User.RequireUniqueEmail = true;
                config.Password.RequiredLength = 8;
            }).AddEntityFrameworkStores<MyApplicationContext>();
            ...

我还使用了Cookie身份验证,之前不再在AddIdentity配置lambda中配置,而是在服务级别完成:

public void ConfigureServices(IServiceCollection services)
    {
        services.ConfigureApplicationCookie(options => options.LoginPath = "/Auth/Login");
        ...

使用派生角色类型对DbContext签名稍作更改:

public class MyApplicationContext : IdentityDbContext<MyApplicationUser, MyRole, int>
{