实体框架代码优先,同一桌上的多对多关系

时间:2016-10-10 16:25:12

标签: entity-framework ef-code-first many-to-many entity code-first

我正在建立一个具有朋友功能的社交网络。 我的想法是我已经有了默认的ApplicationUser类,所以我创建了一个名为朋友的新表

public class Friend
{
    [Key]
    [Column(Order = 1)]
    public string SenderId { get; set; }

    [Key]
    [Column(Order = 2)]
    public string ReceiverId { get; set; }

    //Status == true : Friend request accepted
    //Status == false : Friend request not accepted
    public bool Status { get; set; }
}

ApplicationUser 中,我定义了2个导航属性发件人接收者(以链接到朋友表)

public class ApplicationUser : IdentityUser
{
    [Required]
    [StringLength(50)]
    public string Name { get; set; }

    [Required]
    public bool Gender { get; set; }

    [StringLength(255)]
    public string Address { get; set; }

    [StringLength(255)]
    public string Job { get; set; }

    [StringLength(255)]
    public string Image { get; set; }

    public DateTime Birthday { get; set; }

    public ICollection<ApplicationUser> Senders { get; set; }
    public ICollection<ApplicationUser> Receivers { get; set; }
}

最后在ApplicationDbContext中,我使用Fluent Api

声明了两个表之间的关系
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{

    public DbSet<Friend> Friends { get; set; }

    public ApplicationDbContext()
        : base("DefaultConnection", throwIfV1Schema: false)
    {
    }

    public static ApplicationDbContext Create()
    {
        return new ApplicationDbContext();
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<ApplicationUser>()
            .HasMany(a => a.Senders)
            .WithMany(a => a.Receivers)
            .Map(m =>
            {
                m.MapLeftKey("ReceiverId");
                m.MapRightKey("SenderId");
                m.ToTable("Friends");
            });
        base.OnModelCreating(modelBuilder);

    }
}

但是当我添加迁移时,它创建了两个这样的表,它们都不是我需要的(一个没有外键,一个没有状态属性)

public override void Up()
    {
        CreateTable(
            "dbo.Friends1",
            c => new
                {
                    SenderId = c.String(nullable: false, maxLength: 128),
                    ReceiverId = c.String(nullable: false, maxLength: 128),
                    Status = c.Boolean(nullable: false),
                })
            .PrimaryKey(t => new { t.SenderId, t.ReceiverId });

        CreateTable(
            "dbo.Friends",
            c => new
                {
                    SenderId = c.String(nullable: false, maxLength: 128),
                    ReceiverId = c.String(nullable: false, maxLength: 128),
                })
            .PrimaryKey(t => new { t.SenderId, t.ReceiverId })
            .ForeignKey("dbo.AspNetUsers", t => t.SenderId)
            .ForeignKey("dbo.AspNetUsers", t => t.ReceiverId)
            .Index(t => t.SenderId)
            .Index(t => t.ReceiverId);

    }

我应该怎么做:(我已经在互联网上搜索过,这似乎是合法的,但它不起作用

1 个答案:

答案 0 :(得分:1)

  

但是当我添加迁移时,它创建了两个这样的表,它们都不是我需要的(一个没有外键,一个没有状态属性)

这是因为您混合了EF支持的两个可能的many-to-many关联 - 一个使用隐式联结表(来自Fluent API配置),另一个使用显式联结表(Friend实体)和两个one-to-many协会。

由于第一种方法只有在您没有与该关联相关联的其他数据时才能使用,并且您有一个(Status属性),您需要使用第二种方法。

为此,请按如下所示更改导航属性的类型:

public class ApplicationUser : IdentityUser
{
    // ...
    public ICollection<Friend> Senders { get; set; }
    public ICollection<Friend> Receivers { get; set; }
}

和配置:

modelBuilder.Entity<ApplicationUser>()
    .HasMany(e => e.Senders)
    .WithRequired()
    .HasForeignKey(e => e.ReceiverId);

modelBuilder.Entity<ApplicationUser>()
    .HasMany(e => e.Receivers)
    .WithRequired()
    .HasForeignKey(e => e.SenderId);