简体   繁体   中英

Linq Entity Framework: select table data without repeated data into IEnumerable

I am working with the following technologies: C#, SQL Server, ASP.NET and Entity Framework and Linq.

I have a many-to-many relation in my database:

我的数据库图

The model classes:

public class Courses
{
    [Required]
    public int Id { get; set; }
    //more properties here
     public student stud { get; set; }
}

public class inscribe
{
    [Key]
    public intId { get; set; }
    //properties here
    public student student{ get; set; }
    [Required]
    [ForeignKey("student")]
    public string StudentId{ get; set; }
    public Courses Courses{ get; set; }
}

Given a student Id, I would like to return a list of courses where he/she is inscribed.

This is what I have tried so far:

public IEnumerable<CursoDto> GetCursosAlumno(Int studentId)
{
     //some code here to validate
     var x = _dbContext
                 .Inscribe.Include(c => c.Courses)
                 .Where(c => c.StudentId == studentId).toList();
     // x variable is a list<inscribe>
}

My problem is that I do not know how to access to the courses entity and return it as a list, for instance:

var result = X.Courses;
return result; //result is a list<courses>

How can I do it? If possible, not using a foreach block please.

Thanks

In Code First approach you don't need to add "link table" ( inscribe in OP) into your models (it will be created transparently).

//Models
public class Course
{
    [Key]
    public int Id { get; set; }
    //more properties here
     public virtual /*important*/ ICollection<Student> studs { get; set; }
 }
public class Student
{
    [Key]
    public int Id { get; set; }
    //more properties here
     public virtual /*important*/ ICollection<Course> courses { get; set; }
 }

 //Controller
var stud = _dbContext.studs.Where(s => s.Id == /*param*/id).FirstOrDefault();
var courses = stud.courses.ToList();//Real courses with id, name, etc. No Include required

Update
If you do need the "link table" (for example to add some properties like sortOrder or enrollmentDate ) then the models will be a little different.

//Models
public class Course
{
    [Key]
    public int Id { get; set; }
    //more properties here
     public virtual /*important*/ ICollection<StudentCourse> studs { get; set; }
 }
public class Student
{
    [Key]
    public int Id { get; set; }
    //more properties here
     public virtual /*important*/ ICollection<StudentCourse> courses { get; set; }
 }
[Table("inscribe")]
public class StudentCourse
{
    [Key, Column(Order = 0)]
    public int StudentId {get; set'}
    [Key, Column(Order = 1)]
    public int CourseId {get; set'}
    //extra properties
    [ForeignKey("StudentId")]
    public virtual Student stud { get; set; }
    [ForeignKey("CourseId")]
    public virtual Course course { get; set; }
}

//Controller
var courses = _dbContext.courses.Where(c/*c is "link"*/ => c.Student/*StudentCourse prop*/.Any(s/*link again*/ => s.StudentId == someId/*param*/));//again courses

As you see Include is not required.

var result = _dbContext
    .Inscribe.Include(c => c.Courses)
    .Where(c => c.StudentId == studentId)
    .SelectMany(c => c.Courses).ToList();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM