我正在尝试使用通讯录表创建用户。我不确定我是否以正确的方式进行,因为添加了一个我没有声明的列。
实体:
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来自哪里?我的定义有问题吗?谢谢!
答案 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);
这产生了所需的模式: