ASP.NET Core EF多对多引用表

时间:2016-05-24 16:41:11

标签: c# asp.net asp.net-core entity-framework-core

我正在尝试使用通讯录表创建用户。我不确定我是否以正确的方式进行,因为添加了一个我没有声明的列。

实体:

public class User
{
    public int Id { get; set; }
    public bool IsAvailable { get; set; }
    public List<Contact> Contacts { get; set; }
}

public class Contact
{
    public int UserId { get; set; }
    public int ContactUserId { get; set; }

    public User User { get; set; }
    public User ContactUser { get; set; }
}

映射:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Contact>()
        .HasKey(x => new { x.UserId, x.ContactUserId });

    modelBuilder.Entity<Contact>()
        .HasOne(x => x.User)
        .WithMany(x => x.Contacts)
        .HasForeignKey(x => x.UserId);

    modelBuilder.Entity<Contact>()
        .HasOne(x => x.ContactUser)
        .WithMany(x => x.Contacts)
        .HasForeignKey(x => x.ContactUserId);
}

结果:

migrationBuilder.CreateTable(
    name: "Contact",
    columns: table => new
    {
        UserId = table.Column<int>(nullable: false),
        ContactUserId = table.Column<int>(nullable: false),
        UserId1 = table.Column<int>(nullable: true)
    },
    constraints: table =>
    {
        table.PrimaryKey("PK_Contact", x => new { x.UserId, x.ContactUserId });
        table.ForeignKey(
            name: "FK_Contact_User_ContactUserId",
            column: x => x.ContactUserId,
            principalTable: "User",
            principalColumn: "Id",
            onDelete: ReferentialAction.Cascade);
        table.ForeignKey(
            name: "FK_Contact_User_UserId1",
            column: x => x.UserId1,
            principalTable: "User",
            principalColumn: "Id",
            onDelete: ReferentialAction.Restrict);
    });

真正的问题:

联系人UserId1来自哪里?我的定义有问题吗?谢谢!

1 个答案:

答案 0 :(得分:2)

您最终在联系人表格中添加了 UserId1 的原因是因为您指定了用户 ContactUser 关联的另一面在联系人对象上联系人在用户对象上是不正确的。因此,EF忽略它并在User对象上为 Contacts 创建另一个关联,并将其映射到Contact表上的 UserId1 列。

解决此问题的一种方法是在User对象上创建另一个Contacts列表并相应地映射它:

public class User
{
    public int Id { get; set; }
    public bool IsAvailable { get; set; }

    public List<Contact> Contacts { get; set; }
    public List<Contact> ContactUsers { get; set; }
}

modelBuilder.Entity<Contact>()
    .HasOne(x => x.User)
    .WithMany(x => x.Contacts)
    .HasForeignKey(x => x.UserId);

modelBuilder.Entity<Contact>()
    .HasOne(x => x.ContactUser)
    .WithMany(x => x.ContactUsers)
    .HasForeignKey(x => x.ContactUserId)
    .OnDelete(DeleteBehavior.Restrict);


这产生了所需的模式:

enter image description here