具有联结表的多对多表的正确模型实现

时间:2014-01-16 11:42:41

标签: c# entity-framework junction-table

我没有先使用代码,我创建了一个名为带有ID和名称字段的艺术家的表,一个名为带有id和title字段的专辑的表,以及一个带有artist_id和album_id的junction_artists_albums表。

以下是我的模型/上下文类:

艺术家:

    public class Artist
{
    public int Id { get; set; }
    public string ArtistName { get; set; }

    public ICollection<Album> albums { get; set; }
}

专辑:

    public class Album
{
    public int Id { get; set; }
    public string AlbumName { get; set; }

    public ICollection<Artist> artists { get; set; }


}

MusicDBContext:

    public class MusicDBContext : DbContext
{
    public MusicDBContext() { }

    public DbSet<Artist> Artists { get; set; }
    public DbSet<Album> Albums { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Album>().HasMany<Artist>(a => a.artists).WithMany(a => a.albums);
    }
}

这不起作用,因为没有填写联结表。如果这是一个愚蠢的问题,请原谅我,但我是Entity Framework的新手

1 个答案:

答案 0 :(得分:1)

不,不是那么愚蠢。解决方案很简单。

在处理多对多关系时,除非存在关系字段,否则不需要明确指定联结表。例如,由艺术家制作的专辑,您可能有生产日期等。

你需要做的是改变你用这种方式做的事情

public class Artist
{
    public int Id { get; set; }
    public string ArtistName { get; set; }

    #region Navigation Properties
    public virtual ICollection<Album> Albums { get; set; }
    #endregion
}

public class Album
{
    public int Id { get; set; }
    public string AlbumName { get; set; }

    public virtual ICollection<Artist> Artists { get; set; }
}

我不确切知道这意味着什么,但你可以删除OnModelCreating事件覆盖

请注意,EF Code中的导航属性和外键规范始终是虚拟属性。

当存在多对多关系时,您只需指定相关的导航属性,EF将负责其余部分,并且将使用其中的两个主键创建联结表。如果像我之前告诉你的那样,有一些关系字段,你需要手工创建Junction表,显式创建一个包含键和关系字段的类。

EF中有一些名为conventions的东西,它只是一组您将习惯的命名约定,以及一些可以帮助您显式设置外键等的装饰器。