简体   繁体   中英

Entity framework one to many

I am using Entity Framework and have the following classes

class Student
{
 [Key]
 public virtual int StudentID {get; set;}
 public virtual string StudentName {get; set;}
 public virtual ICollection<Note> Notes {get; set;}
}
class Note
{
 [Key]
 public virtual int NoteID {get; set;}
 public virtual int StudentID {get; set;}
 public virtual string Message {get; set;}
}
class StudentDBContext:DbContext
{
 public DbSet<Student> Students { get; set; }
 public DbSet<Note> Notes { get; set; }
}

So to summarize, I have a class of students who can each have many notes. Now, I want to use Linq to retrieve and display all the notes for a particular student. So I try

using (StudentDBContext a = new StudentDBContext())
{
 var b = from c in a.Student
         where c.StudentID == 1001
         select c;

 var currStudent = b.FirstOrDefault();
 Console.WriteLine(currStudent.StudentName);

  //display all the messages of the current student
  foreach (var currNote in currStudent.Notes)
  Console.WriteLine(currNote.Message);
}

In the above code, my foreach block always fails because Student.Notes is always null. Am I missing some step in initializing Student.Notes and populating it from the database?

Your class Student and Note should be public.

The following code runs:

class Program {
    static void Main(string[] args) {
        using ( StudentDBContext efc = new StudentDBContext()) {
            foreach (var v in efc.Students) {
                Console.WriteLine("{0}", v.StudentName);
                foreach (var vv in v.Notes) {
                    Console.WriteLine("    {0}", vv.Message);
                }
            }
        }
    }
}

public class Student {
    public Student() {
        //Notes = new List<Note>();
    }
     [Key]
     public int StudentID {get; set;}
     public virtual string StudentName {get; set;}
     public virtual ICollection<Note> Notes {get; set;}
}
public class Note {
 [Key]
 public int NoteID {get; set;}
 public int StudentID {get; set;}
 public string Message {get; set;}
}
class StudentDBContext:DbContext {
    public DbSet<Student> Students { get; set; }
    public DbSet<Note> Notes { get; set; }        
}

try this:

using (StudentDBContext a = new StudentDBContext())
{
   var b = ((from c in a.Student
           join b in a.Notes on b.StudentId equals c.StudentId into sNotes
                 from notes in sNotes.DefaultIfEmpty()
           where c.StudentId==1001
           select c).SingleOrDefault();
   if (b != null )
     ...
}

Be aware of the fact that Entity Framework will do a lazy load of your data. So if you don't do something to populate it then you will not get it. There are other ways of doing it but among other things this query clearly documents that you are wanting both the student and notes.

This shouldn't be virtual.

public virtual NoteID {get; set;} 

It should be an integer:

public int NoteID {get; set;}

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