TheCoder
TheCoder

Reputation: 155

One to many config in Entity Framework and Join Expressions

I am using EF codefirst .I am confused on relationship in Entities .I have Two entities Student and Standard . Shown below

public class Student
{
    public int StudentId { get; set; }
    public string StudentName { get; set; }
    public int StdandardId { get; set; }
}

public class Standard
{
    public int StandardId { get; set; }
    public string StandardName { get; set; }
    public string Description { get; set; }
}

They have One to Many relationship. I can do this by simple join expression like this

var list = StudentList.Join
          (StandardList,c => c.StdandardId,o => o.StandardId,(c, o) => new
          {
              StudentId = c.StudentId,
              StudentName = c.StudentName,
              StandardName = o.StandardName
          });

Then why should i configure forienkey One-to-Many relationship like

public class Student
{
    public Student() { }
    public int StudentId { get; set; }
    public string StudentName { get; set; }
    public int StdandardId { get; set; }    
    public virtual Standard Standard { get; set; }
}

public class Standard
{
    public Standard()
    {
        Students = new List<Student>();
    }

    public int StandardId { get; set; }
    public string StandardName { get; set; }
    public string Description { get; set; }
    public virtual ICollection<Student> Students { get; set; }
}

Is there any key benifits.? Which one will perform well ?

Upvotes: 1

Views: 103

Answers (2)

Gert Arnold
Gert Arnold

Reputation: 109253

The navigation property (Students) is an implicit join. but it's an outer join. If you join explicitly you can enforce an inner join, which will generally perform better. So do this if performance is critical.

So give yourself the opportunity to do both. Create navigation properties and join explicitly when necessary.

The benefit of navigation properties is a much more succinct syntax. e.g.

from standard in Standards
select new { standard.StandardName , NrOfStudents = standard.Students.Count() })

For this query you always want an outer join, because you'd also want to report the standards with zero students.

Or an implicit SelectMany:

from standard in Standards
where standard.StandardId == id
from student in standard.Students
select new { student. ... }

Navigation properties help you to carry out joins without this verbose join syntax.

Upvotes: 3

Marco
Marco

Reputation: 23945

This question can result in answers ranging to the size of essays.

I'll try to keep it essential. In short, Foreign Keys are used to ensure referential integrity.

In your select statement it might not make a difference, but think about update, insert and delete statements, and hurdles you'd have to take in order to cascade everything down to the last table.

Lets assume your Foreign Key constraint is set to Cascade. Whenever you make a change in your mastertable, the change is cascaded down to every child table. You'd have to manually join every table in your statement to implement the same.

If the constraint is set to Restrict you can not delete a Student as long as there are still Standards referencing to it. Again, You'd have to check this by hand in your statements every time.

You may very well be able to do this in your head, but you will make an error, and then you may be stuck with inconsistent data, when money is on the line.


And then there is comfort in EF.

I could join my data, but if there are Foreign Keys and tehrefore relationships in place I could write

var students = context.Students.Include(o => o.Enrollments);

and use it in my View with

@foreach(var enrollment in Model.Enrollments)
{
   //...
}

In essence, this is not a problem related purely to Entity Framework, but to relational databases.

Have a look at ACID and Foreign Keys

Upvotes: 2

Related Questions