Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple collections of same type in entity framework

I have these two very simple classes.

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public Group Group { get; set; }
}

public class Group
{
    public int Id {get;set;}
    public ICollection<Person> Teachers { get; set; }
    public ICollection<Person> Students { get; set; }
}

I would like EF to keep Teachers seperated from Students however they both get jumbled into a Person table with no way to distinguish between them.

Any ideas?

like image 271
Toodleey Avatar asked Mar 25 '14 07:03

Toodleey


3 Answers

A little bit different case (when class is holding reference to two identical objects), but can be helpful:

    public class Mission
{
    //DB objects
    public int Id { get; set; }
    public int SourceLocationId {get; set}
    public int DestinationLocationId {get; set}

    //Virtual objects
    public virtual Location SourceLocation { get; set; }
    public virtual Location DestinationLocation { get; set; }

}

public class Location
{
    //DB objects
    public int Id {get;set;}

    //Virtual objects
    public virtual ICollection<Mission> SourceMissions { get; set; }
    public virtual ICollection<Mission> DestinationMissions { get; set; }
}

Then all you need to do is bind it properly in OnModelCreating:

   modelBuilder.Entity<Mission>()
        .HasOptional(m => m.SourceLocation)   //Optional or Required
        .WithMany(sm => sm.SourceMissions)
        .HasForeignKey(to => to.SourceLocationId);

    modelBuilder.Entity<Mission>()
        .HasOptional(m => m.DestinationLocation)   //Optional or Required
        .WithMany(sm => sm.DestinationMissions)
        .HasForeignKey(to => to.DestinationLocationId);
like image 23
Qjot Avatar answered Nov 11 '22 21:11

Qjot


There are two ways to do it;

first : use a tag or enums in the Person object

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public Group Group { get; set; }
    public bool IsFaculty { get; set; }
}

or

public enum PersonType { Teacher, Student }; 

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public Group Group { get; set; }
    public PersonType PropPersonType { get; set; }
}

second : work object oriented with inheritance. This method has my preference because it's easy to manage and expand if you want to expand it.

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public Group Group { get; set; }
}


public class Student : Person
{
    public int Year { get; set; }
    // other student related fiels.
}


public class Teacher : Person
{
    public List<Course> Courses { get; set; }
    // other teacher related fields
}

Your Group is then

public class Group
{
    public int Id {get;set;}
    public ICollection<Teacher> Teachers { get; set; }
    public ICollection<Student> Students { get; set; }
}
like image 145
KarelG Avatar answered Nov 11 '22 20:11

KarelG


Separate in two different classes, and then inherit both of them with Person, because all the teachers and students are Persons, but not all Persons are teachers and students.

public class Person
{
}

public class Teacher : Person
{
}

public class Student : Person
{
}

I hope this helps

like image 1
Oscar Bralo Avatar answered Nov 11 '22 21:11

Oscar Bralo