我有一张桌子(艺术家),与自己有很多关系(艺术家可以是一个乐队或一个人)。
我的课程在下面声明:
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);
乐队是作为独唱艺人的成员创作的。然而,它正确地存储在数据库中。
在实体框架中正确存储关系需要做些什么?
答案 0 :(得分:1)
您的映射已反转,因为每个modelBuilder语句都描述了一个关系。你现在有:
Artist.Members <---- inverse of ----> ArtistMember.Member
Artist.MemberOf <---- inverse of ----> ArtistMember.Band
这是没有意义的,因为如果bandArtist
有Members
,ArtistMember
对象加入bandArtist
和Members
,{{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
行可能没有意义。