Как создать сопоставление "многие-ко-многим" в Entity Framework?

Вот так, у меня есть 2 объекта, такие как Contract, Media.

public class Media : Entity
{
    public string Name {get; set;}
    public bool Enabled
    *//other properties can be ignored..*
}

public class Contract : Entity
{
    public string Code {get; set;}
    *//other properties can be ignored..*
}

В контракте есть много Medias, кажется, что их много.

Но!! сначала в ef-коде, мне нужно еще 3 поля в таблице ContractMedia (ef auto generated). таких как StartDate, EndDate и Price. они не могут быть добавлены в объект Media.

Как нарисовать карту в этом случае?

Ответ 1

Если вы хотите создать много-много отношений с дополнительными данными в таблице объединений, вы должны сделать таблицу ассоциации как сущность. Чистые отношения "многие-многие" относятся только к чистой таблице с идентификатором сущности.

В вашем случае это будет:

public class Media // One entity table
{
    public int Id { get; set; }
    public string Name { get; set; }
    public bool Enabled { get; set; }

    public virtual ICollection<ContractMedia> ContractMedias { get; set; }
}

public class Contract // Second entity table
{
    public int Id { get; set; }
    public string Code { get; set }

    public virtual ICollection<ContractMedia> ContractMedias { get; set; }
}

public class ContractMedia // Association table implemented as entity
{
    public int MediaId { get; set; }
    public int ContractId { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }
    public double Price { get; set; }

    public virtual Media Media { get; set; }
    public virtual Contract Contract { get; set; }
}

И после создания моделей/сущностей вам необходимо определить отношения в контексте:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
   modelBuilder.Entity<ContractMedia>()
       .HasKey(c => new { c.MediaId, c.ContractId });

   modelBuilder.Entity<Contract>()
       .HasMany(c => c.ContractMedias)
       .WithRequired()
       .HasForeignKey(c => c.ContractId);

   modelBuilder.Entity<Media>()
       .HasMany(c => c.ContractMedias)
       .WithRequired()
       .HasForeignKey(c => c.MediaId);  
}

Также вы можете ссылаться на эти ссылки:
Множество ссылок на дополнительные поля в Fluent API
Entity Framework CodeFirst многие-многие отношения с дополнительной информацией
Сначала создайте код, многие для многих, с дополнительными полями в таблице ассоциации

Ответ 2

Добавление к @Tomas ответа без использования Fluent API.

public class Media // One entity table
{
    public int Id { get; set; }

    public string Name { get; set; }

    public virtual ICollection<ContractMedia> ContractMedias { get; set; }
}

public class Contract // Second entity table
{
    public int Id { get; set; }

    public string Code { get; set }

    public virtual ICollection<ContractMedia> ContractMedias { get; set; }
}

public class ContractMedia // Association table implemented as entity
{
    [Key]
    [Column(Order = 0)]
    [ForeignKey("Media")]
    public int MediaId { get; set; }

    [Key]
    [Column(Order = 1)]
    [ForeignKey("Contract")]
    public int ContractId { get; set; }

    public DateTime StartDate { get; set; }

    public DateTime EndDate { get; set; }

    public double Price { get; set; }

    public virtual Media Media { get; set; }

    public virtual Contract Contract { get; set; }
}