Let us see how we can manipulate child entity from the parent entity
Create a child entity
Let us continue the same example; make the changes to program file in order to experiment the following commands. Below are the list of students
using EFGetStarted;
using System;
using System.Linq;
var db = new MyContext();
Console.WriteLine("List of students...\n");
foreach (var s in db.Students)
Console.WriteLine($" Id: {s.Id}\t Name: {s.Name} Is Enrolled: {s.IsEnrolled}");
Console.WriteLine();
Console.WriteLine("Press any key to exit");
Console.ReadKey();
List of students...
Id: 1 Name: Sam Is Enrolled: True
Id: 2 Name: Ted Is Enrolled: False
Id: 3 Name: Kim Is Enrolled: False
Press any key to exit
let us add a new vehicle entity
Let us create a new vehicle for student with Id 1 as follows
using EFGetStarted;
using System;
var db = new MyContext();
var v1 = new Vehicle(){ Name = "Honda"};
var s1 = db.Students.Find(1);
s1.Vehicles.Add(v1);
db.SaveChanges();
Console.WriteLine("Done");
Console.WriteLine("Press any key to exit");
Console.ReadKey();
At this point, if you look at the database you should see a new row in the vehicles table as shown
Retrieve a child entity
Let us retrieve the same vehicle from the student reference as follows
(This will not work)
using EFGetStarted;
using System;
var db = new MyContext();
var s1 = db.Students.Find(1);
var v = s1.Vehicles.First();
Console.WriteLine(v.Name);
Console.WriteLine("Press any key to exit");
Console.ReadKey();
Not working?
In the classic entity framework this query would work fine, but now you get an exception!
That is because when student information is loaded from the database (line number 6) the related entities i.e., his vehicles is not loaded by entity framework core because it could create performance issues!
However, at line 7 EF core could have fetched the first the vehicle in question - using a technique called lazy loading (load something later when required)
But entity framework core decided not to use lazy loading out of the box! out of we can configure that on demand.
However, we need to use a technique called eager loading. Change line number 6 to the following:
var s1 = db.Students.Include(i => i.Vehicles).First();
We can similarly include any related entities this way. You can include related data from multiple relationships in a single query. Fo example:
using (var context = new BloggingContext())
{
var blogs = context.Blogs
.Include(blog => blog.Posts)
.Include(blog => blog.Owner)
.ToList();
}
Honda
Press any key to exit
Manipulate parent
Retrieve parent entity
let us try to retrieve parent entity from child. Remember we have navigation properties for parent, in child definition!
using EFGetStarted;
using Microsoft.EntityFrameworkCore;
using System;
var db = new MyContext();
var v1 = db.Vehicles.First();
Console.WriteLine(v1.Name);
Console.WriteLine(v1.Student.Name);
Console.WriteLine("Press any key to exit");
Console.ReadKey();
Honda
Unhandled exception. System.NullReferenceException: Object reference not set to an instance of an object.
at Program.<Main>$(String[] args) in C:\Users\ravi_\Source\repos\Experiments\EF Experiments\EFGetStarted\Program.cs:line 10
replace line 7 with the following
Let us eager load the parent as well!
var v1 = db.Vehicles.Include(i => i.Student).First();
Honda
Sam
Press any key to exit
Delete parent entity
What happens if we try to delete the parent entity since there are children associated with it
Let's first create some records
using EFGetStarted;
using Microsoft.EntityFrameworkCore;
using System;
var db = new MyContext();
var s = new Student() { Name = "Jack", City = "Mys" };
var v = new Vehicle() { Name = "Suzuki" };
s.Vehicles.Add(v);
db.Students.Add(s);
db.SaveChanges();
Console.WriteLine("Done saving");
Console.WriteLine("Press any key to exit");
Console.ReadKey();
When creating 2 objects related to each other, add to the DBSet the object which we use to form the association! The primary key and the foreign keys will be generated and used accordingly by entity framework itself.
In other words if you use the parent object to form the association add the parent object if you use the child object to form the association add the child object to the DBSet
Now let's delete the student Jack
using EFGetStarted;
using Microsoft.EntityFrameworkCore;
using System;
var db = new MyContext();
var s = db.Students.Find(5);
db.Students.Remove(s);
db.SaveChanges();
Console.WriteLine("Done");
Console.WriteLine("Press any key to exit");
Console.ReadKey();
What happens on delete?
Remember we have cascade on delete by default. That means, along with the parent the child entities are also deleted! We can change this behavior if required!
Using navigation properties, we can deal with entities as if they were in memory collection of objects and not database records! This is the advantage of using an ORM framework like entity framework core! Of course, needless to mention the mapping of database column values on to object properties which happens behind the scenes!