EF Core 2.1 - How to map Many-To-Many with same Types

.net-core c# entity-framework-core

Question

I have a very specific problem, which I would like to ask here for help. I'm using .NET Core 2.1.1 with EF Core 2.1.1. I'm using the code first approach and currently am designing a domain model for my application.

So I have the following requirement: I have a TrainingItem class, which contains basic information about training. TrainingItem also contains a list of attendees, so I am using the many-to-many relationship between TrainingItem and TrainingEmployee. The problem is that I have a requirement that TrainingItem should contain a list of employees that are waiting for this training, so I came up with the following approach:

public class TrainingItem 
{
  // ... properties for Training
  public virtual ICollection<TrainingEmployeeTrainingItem> Attendees {get;set;} = new List<TrainingEmployeeTrainingItem>();

  public virtual ICollection<TrainingEmployeeTrainingItem> WaitingList {get;set;} = new List<TrainingEmployeeTrainingItem>();  
}

public class TrainingEmployee
{
    // ... properties for Employee
    public virtual ICollection<TrainingEmployeeTrainingItem> TrainingEmployeeTrainingItems {get;set;} = new List<TrainingEmployeeTrainingItem>();
}

public class TrainingEmployeeTrainingItem
{
    public int TrainingEmployeeId {get;set;}
    public virtual TrainingEmployee TrainingEmployee {get;set;}

    public int TrainingItemId {get;set;}
    public virtual TrainingItem TrainingItem {get;set;}
}

// this is my model creating method in db context
protected override void OnModelCreating(ModelBuilder builder)
{
    // many-to-many
    builder.Entity<TrainingEmployeeTrainingItem>()
        .HasKey(x => new { x.TrainingEmployeeId, x.TrainingItemId });
}

So as you can see the first list of attendees can be mapped with a workaround that is currently in EF Core used for mapping many-to-many relationships.

But the question is, how can I map WaitingList?

1
2
8/17/2018 3:05:35 PM

Accepted Answer

You need an extra entity per many-to-many, so only TrainingEmployeeTrainingItem won't do.

Try the following:

public class TrainingItem 
{
  // ... properties for Training
  public virtual ICollection<AttendeeTrainingEmployeeTrainingItem> Attendees {get;set;} = new List<AttendeeTrainingEmployeeTrainingItem>();

  public virtual ICollection<WaitingListTrainingEmployeeTrainingItem> WaitingList {get;set;} = new List<WaitingListTrainingEmployeeTrainingItem>();  
}

public class TrainingEmployee
{
    // ... properties for Employee
    public virtual ICollection<AttendeeTrainingEmployeeTrainingItem> AttendingTrainings {get;set;} = new List<AttendeeTrainingEmployeeTrainingItem>();
    public virtual ICollection<WaitingListTrainingEmployeeTrainingItem> AwaitingTrainings {get;set;} = new List<WaitingListTrainingEmployeeTrainingItem>();
}

public abstract class TrainingEmployeeTrainingItem
{
    public int TrainingEmployeeId {get;set;}
    public virtual TrainingEmployee TrainingEmployee {get;set;}

    public int TrainingItemId {get;set;}
    public virtual TrainingItem TrainingItem {get;set;}
}

public class AttendeeTrainingEmployeeTrainingItem : TrainingEmployeeTrainingItem
{
}

public class WaitingListTrainingEmployeeTrainingItem : TrainingEmployeeTrainingItem
{
}

// this is my model creating method in db context
protected override void OnModelCreating(ModelBuilder builder)
{
    // many-to-many
    builder.Entity<AttendeeTrainingEmployeeTrainingItem>()
        .HasKey(x => new { x.TrainingEmployeeId, x.TrainingItemId });
    builder.Entity<WaitingListTrainingEmployeeTrainingItem>()
        .HasKey(x => new { x.TrainingEmployeeId, x.TrainingItemId });
}
3
8/16/2018 1:39:25 PM

Popular Answer

I answered this question before (it's worth noting your question is not a duplicate because it's for core and not old school EF).

You can apply the InversePropertyAttribute to your collections.



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow