实体框架 - 多对多自我加入逆转

时间:2015-05-27 12:08:08

标签: entity-framework

我有一张桌子(艺术家),与自己有很多关系(艺术家可以是一个乐队或一个人)。

我的课程在下面声明:

public class Artist
{
    public int ID { get; set; }
    public string Name { get; set; }

    public virtual ICollection<ArtistMember> Members { get; set; }
    public virtual ICollection<ArtistMember> MemberOf { get; set; }
}

public class ArtistMember
{
    public int BandID { get; set; }
    public int MemberID { get; set; }
    public bool Active { get; set; }
}

并在此处映射:

modelBuilder.Entity<Artist>()
    .HasMany(e => e.Members)
    .WithRequired(e => e.Member)
    .HasForeignKey(e => e.MemberID)
    .WillCascadeOnDelete(false);

modelBuilder.Entity<Artist>()
    .HasMany(e => e.MemberOf)
    .WithRequired(e => e.Band)
    .HasForeignKey(e => e.BandID)
    .WillCascadeOnDelete(false);

modelBuilder.Entity<ArtistMember>().ToTable("ArtistMember", "Music").HasKey(am => new { am.BandID, am.MemberID });

问题在于,当我想将数据插入到结构中时,我必须将其反转以使其起作用。

// Create New Band
TRN.Models.Artist b = new Artist();
b.Name = "Band";

// Create New Member
TRN.Models.Artist m = new Artist();
m.Name = "Member";

// Create Link
ArtistMember am = new ArtistMember();
am.Band = b;
am.Member = m;

b.MemberOf.Add(am);

乐队是作为独唱艺人的成员创作的。然而,它正确地存储在数据库中。

在实体框架中正确存储关系需要做些什么?

1 个答案:

答案 0 :(得分:1)

您的映射已反转,因为每个modelBuilder语句都描述了一个关系。你现在有:

Artist.Members  <---- inverse of ----> ArtistMember.Member
Artist.MemberOf <---- inverse of ----> ArtistMember.Band

这是没有意义的,因为如果bandArtistMembersArtistMember对象加入bandArtistMembers,{{1}应该引用ArtistMember.Band

我认为你在寻找:

bandArtist

这意味着你需要:

Artist.Members  <---- inverse of ----> ArtistMember.Band
Artist.MemberOf <---- inverse of ----> ArtistMember.Member

从关系的另一面开始甚至更有意义:

modelBuilder.Entity<Artist>()
    .HasMany(e => e.Members)
    .WithRequired(e => e.Band)
    .HasForeignKey(e => e.BandID);

modelBuilder.Entity<Artist>()
    .HasMany(e => e.MemberOf)
    .WithRequired(e => e.Member)
    .HasForeignKey(e => e.MemberID);

因此,如果你正在寻找乐队的成员,你会做类似的事情:

modelBuilder.Entity<ArtistMember>()
    .HasRequired(e => e.Band)
    .WithMany(e => e.Members)
    .HasForeignKey(e => e.BandID);

modelBuilder.Entity<ArtistMember>()
    .HasRequired(e => e.Member)
    .WithMany(e => e.MemberOf)
    .HasForeignKey(e => e.MemberID);

顺便说一句,我删除了bandArtist.Members.Select(am => am.Member) ,因为如果删除任何一方的相应WillCascadeOnDelete(false),则留下流浪ArtistMember行可能没有意义。