EF核心-跨4个表的多对多关系

时间:2018-07-27 23:15:28

标签: entity-framework orm relational-database ef-core-2.1

请考虑以下3个实体ABCAC是多对多关系。 BA是一对多关系(B有很多A,这意味着BC也是多对多)。

如果这些过于复杂的关系对您来说似乎太含糊,请考虑以下示例:

  • 一个TrackA)有多个ArtistC),一个Artist有多个Track s(许多-很多)
  • 一个AlbumB)有多个Track。 (一对多,Track 不能属于多个Album s)

这样(表示):

  • Album有多个Artist,而Artist有多个Album(多对多)

问题:如何使实体具有这种关系?通过以下代码,我建立了AlbumArtistTrack-到-Artist如何创建Artist-Album关系,因为它似乎需要连接4个表/实体。

public class Context: DbContext
{

    // irrelevant code omitted...        

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<TracksToArtists>()
            .HasKey(r => new {r.TrackId, r.ArtistId});

        modelBuilder.Entity<TracksToArtists>()
            .HasOne(r => r.Track)
            .WithMany(t => t.Artists)
            .HasForeignKey(r => r.TrackId);

        modelBuilder.Entity<TracksToArtists>()
            .HasOne(r => r.Artist)
            .WithMany(a => a.Tracks)
            .HasForeignKey(r => r.ArtistId);
    }
}

public class Track
{
    public Guid Id { get; set; }
    public string Name { get; set; }

    public Guid AlbumId { get; set; }
    public Album Album { get; set; }

    public List<TracksToArtists> Artists { get; set; }
}

public class Album
{
    public Guid Id { get; set; }
    public string Name { get; set; }

    public List<Track> Tracks { get; set; }

    // TODO: create album-to-artist many-to-many relationship
    // public List<SomethingArtistMaybe?> Artists { get; set; }
}
public class Artist
{
    public Guid Id { get; set; }
    public string Name { get; set; }

    public List<TracksToArtists> Tracks { get; set; }

    // TODO: create album-to-artist many-to-many relationship
    // public List<SomethingAlbumMaybe?> Albums { get; set; }
}
 // many-to-many relationship
public class TracksToArtists
{
    public Guid TrackId { get; set; }
    public Track Track { get; set; }

    public Guid ArtistId { get; set; }
    public Artist Artist { get; set; }
}

如果仅使用原始SQL查询,这非常简单,但是使用ORM,一切都会变得有些痛苦。

最佳,我想避免引入AlbumToArtist表,因为它可能会导致数据不一致。应该是这样的:

1 个答案:

答案 0 :(得分:0)

如果我对您的理解正确,那么ArtistAlbum没有直接关系,这种关系只能通过Track来实现。

考虑将Album放在中间,这样每个Artist都有多个Album,反之亦然(多对多),然后让Album导航到Track个(一对多)。

无论如何,无论您是选择保留模型还是按照我的建议,从点到另一点(在您的问题中,每个Album的{​​{1}}个)访问图形,都使用{{ 3}}:

Artist

您还可以启用eager loading,这样就不必在查询中明确包含导航属性,但是这样做会降低性能。