Entity Framework model to Json Result - c#

I confused with error that Action returns me. I have a code in my manager:
public class AddressesManager
{
private SiteDBEntities entityContext;
public Addresses GetAddress(short id)
{
entityContext = new SiteDBEntities();
var addressList = entityContext.Addresses.Where(a => a.Id == id).FirstOrDefault();
entityContext.Dispose();
return addressList;
}
}
And action that call this function:
[HttpPost]
public ActionResult LoadAddress(short id)
{
AddressesManager mngr = new AddressesManager();
Addresses address = mngr.GetAddress(id);
return new JsonResult() { Data = address };
}
And jquery code wich call thit action:
$.post("/Cart/LoadAddress", { id: id })
.success(function (data) {
console.log(data);
})
.fail(function (e) { console.log(e) });
Action is running, but i always getting 500 error whit this code:
The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.
As i understood the problem is with entityContext , but why this happens? I already executed data from DB and I don't need connection anymore...
EDIT:
Thit is my Address model. It autogenerated by EF:
public partial class Addresses
{
public int Id { get; set; }
public string Title { get; set; }
public string State { get; set; }
public string Country { get; set; }
public string Warehouse { get; set; }
public string FirstName { get; set; }
public string SecondName { get; set; }
public string Phone { get; set; }
public short DeliveryType { get; set; }
public System.Guid UserId { get; set; }
public virtual DeliveryType DeliveryType1 { get; set; }
public virtual Users Users { get; set; }
}

The error happens because your Address class has 2 virtual properties: DeliveryType1 and Users.
When you convert your address to JSON, it will try to access those virtual properties. However, at that time, your context are disposed already.
To avoid this problem, you shouldn't return the EF auto-generated class directly. Instead, create a DTO object (Data Transfer Object) containing only some fields you need, map it with the EF object, and return it. For example:
public class AddressesDTO
{
public int Id { get; set; }
public string Title { get; set; }
public string State { get; set; }
public string Country { get; set; }
public string Warehouse { get; set; }
public string FirstName { get; set; }
public string SecondName { get; set; }
public string Phone { get; set; }
public short DeliveryType { get; set; }
public System.Guid UserId { get; set; }
}
Then, map it:
public Addresses GetAddress(short id)
{
entityContext = new SiteDBEntities();
var addressList = entityContext.Addresses.Where(a => a.Id == id).FirstOrDefault();
// Create DTO object
AddressesDTO address = new AddressesDTO();
// Map it
address.Id = addressList.Id;
address.Title = addressList.Title
// Go on, it's quite long...
entityContext.Dispose();
return address;
}
However, as you can see, the mapping process is very boring. A better way is using Automapper.

If you want to use your entity data model then I suggest you to take a look to my answer in this post.
Now, what I would do is create a DTO to get only the data you need to pass to your View, like was proposed by #AnhTriet. To avoid map by yourself each property every time you need to project your query to your DTO, I suggest to use Automapper. Let me show you how would be your solution if you decide to use it:
public class AddressesManager
{
public Addresses GetAddress(short id)
{
using(var entityContext = new SiteDBEntities())
{
var address = entityContext.Addresses
.Where(a => a.Id == id)
.ProjectTo<AddressDTO>()
.FirstOrDefault();
return address;
}
}
}
About ProjectTo extension method.

Do you have a navigation (child) property in your Address class? I get the feeling that you're trying to access this child property after the DbContext has been disposed of, as child properties are lazy-loaded by default.
Can you post the code of your Address model?

I think you should add attribute [JsonIgnore] to virtual properties of Addresses Class.
class Addresses
{
public int ID { get; set; }
[JsonIgnore]
public virtual Something Something { get; set; }
}

Addresses should be lazy-loaded in your case. So you are trying to access disposed data and Entity Framework tries to use disposed context and that gives an exception.
Maybe you need to attach your addressList to current context in order to enable lazy-loading
var addressList = entityContext.Addresses.Where(a => a.Id == id).FirstOrDefault();
entityContext.Addresses.Attach(addressList);

When you are returning a json record in MVC you need to add AllowGet like so in your controller:
return Json(new { data= address }, JsonRequestBehavior.AllowGet);
With this in place you should be fine.

Related

How should I pass the author of the change into PUT/POST methods?

I have a Category class which looks like this:
public class Category
{
[Required]
public Guid Id { get; set; }
[Required]
public string CategoryName { get; set; }
public string CategoryDescription { get; set; }
public DateTime CreatedDate { get; set; }
public bool isDeleted { get; set; } = false;
public virtual ICollection<UpdateInfo> Updates { get; set; } = new List<UpdateInfo>();
}
And a UpdateInfo class which looks like this (with enum):
public enum Status
{
Created,
Changed,
Deleted
}
public class UpdateInfo
{
public Guid Id { get; set; }
public string Author { get; set; }
public DateTime Date { get; set; }
public Status Status { get; set; }
public virtual Category Category { get; set; }
}
I am looking for a proper way to pass the author into PUT/POST/DELETE methods together with Id or CategoryDTO passed from body. I tried it with POST method first, and I need an opinion, and the proper way to do this.
[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status409Conflict)]
public async Task<ActionResult<Category>> PostCategory(CategoryDTO categoryDTO, string author)
{
_logger.LogInformation("Creating a new category DB object from a DTO objcect passed in PostOperation method.");
var category = _mapper.Map<CategoryDTO, Category>(categoryDTO);
if (CategoryRepeat(category.CategoryName))
{
return Conflict("Such category already exists.");
}
_logger.LogInformation("Adding an initial update status.");
var initialUpdate = new UpdateInfo { Author = author, Status = Status.Created, Date = DateTime.UtcNow, Id = Guid.NewGuid(), Category = category };
category.Updates.Add(initialUpdate);
try
{
_logger.LogInformation($"Trying to save created category {category.Id} into the Database.");
_context.Categories.Add(category);
await _context.SaveChangesAsync();
_logger.LogInformation($"Created category id: {category.Id} saved into the Database successfully.");
}
catch (DbUpdateConcurrencyException ex)
{
_logger.LogError(ex.Message);
return BadRequest(new { message = ex.Message });
}
return CreatedAtAction("GetCategory", new { id = category.Id }, category);
}
The way you did it by passing it as a separate variable might be more flexible if you need to pass the author in some requests but not others. So you did good. If you see yourself that you are passing the author everywhere, it would be better to change the CategoryDTO model instead.
Another way would be to make another DTO for the specific action you are looking for. For example CreateCategoryDTO for "create" POST requests and change the model there instead. It really depends on your coding style and the whole "coding standard" of your project.
If I understood your problem correctly, you could also pass the author in the request header. you can create a custom header and set it when sending the request then you can get the info like string author = Request.Headers["Header-Author"];
another way is to add the property to the existing CategoryDTO itself. then get it like string author = categoryDTO.Author;
one way is as you have done by passing as a separate parameter.

Handling Nested Objects in Entity Framework

I am struggling a bit to wrap my head around Entity Framework and It's driving me crazy. I have an target object that I'd like to populate:
public class ApiInvitationModel
{
public int Id { get; set; }
public EventModel Event { get; set; }
public UserModel InvitationSentTo { get; set; }
public UserModel AttendingUser { get; set; }
}
The schemas of the above models are:
public class EventModel {
public int Id? { get; set; }
public string Name { get; set; }
public DateTime? StartDate { get; set; }
public DateTime? EndDate { get; set }
public OrganizationModel HostingOrganization { get; set; }
public Venue Venue { get; set; }
public string Price { get; set; }
}
public class UserModel {
public int Id? { get; set; }
public string Name { get; set; }
public string PhoneNumber { get; set; }
public string MobileNumber { get; set; }
public List<OrganizationModel> Organizations { get; set; }
}
public class OrganizationModel {
public int Id? { get; set; }
public stirng Name { get; set; }
public string Address { get; set; }
public UserModel PrimaryContact { get; set; }
}
The above schemas are simplified for the purpose of the question and are the models we intend to return via API.
The problem is the origin schemas in the database is very different and I'm trying to map the database objects to these objects via Entity Framework 6.
My attempted solution was to try and nest the models via a query but that didn't work and I'm not sure where to go from here besides making numerous calls to the database.
public List<ApiInvitationModel> GetInvitations(int userId) {
using (var entities = new Entities()) {
return entities.EventInvitations
.Join(entities.Users, invitation => invitiation.userId, user => user.id, (invitation, user) => new {invitation, user})
.Join(entities.Events, model => model.invitation.eventId, ev => ev.id, (model, ev) => new {model.invitation, model.user, ev})
.Join(entities.organization, model => model.user.organizationId, organization => organization.id, (model, organization) => new ApiInvitationModel
{
Id = model.invitation.id,
Event = new EventModel {
Id = model.event.id,
Name = model.event.name,
StartDate = model.event.startDate,
EndDate = model.event.endDate,
HostingOrganization = new OrganizationModel {
Id = model.invitation.hostingId,
Name = model.event.venueName,
Address = model.event.address,
PrimaryContact = new UserModel {
Name = model.event.contactName,
PhoneNumber = model.event.contactNumber,
}
}
...
},
InvitedUser = {
}
}
).ToList();
}
}
As you can see above, there's quite a bit of nesting going on but this doesn't work in Entity Framework 6 as far as I am aware. I keep getting the following errors:
"The type 'Entities.Models.API.UserModel' appears in two structurally incompatible initializations within a single LINQ to Entities query. A type can be initialized in two places in the same query, but only if the same properties are set in both places and those properties are set in the same order.",
Based on the above error, I assumed that each of the model initiatilizations would need to be the same (i.e. initializing the values as the same ApiInvitationModel in each join in the same order) but that produces the same error.
What would be the best approach to handling this, keepign in mind the source database doesn't have foreign keys implemented?

EF Core returns only first record of a list unless FK entities are reset

I am facing the same issue as described in this question. Problem: my method GetAllConferences() returns correctly all the conferences from the DB, but when I return the result to the View from the controller return Ok(tripListVm) inly the first collection item is returned to the client. On the otehr side, by setting to null all the FK references (as pointed out in the SO question above) I can return correctly all the entities to the client, however this does not seem to me the proper way of proceeding.
EDIT: the solution was much simpler than I though. In the code below (I leave it in its original form for others to see it) I was not mapping the FK entities inside the ViewModel to Dto objects, but returning the model entity itself. That was the reason why I needed to null those inner references to make it work. By returning all Dtos objects, it works properly.
I have three entities involved with 1-many relationships:
public class Conference
{
public int Id { get; set; }
[Required]
[MaxLength(50)]
public string Name { get; set; }
public ICollection<Venue> Venues { get; set; }
public int? LocationId { get; set; }
public Location Location { get; set; }
}
public class Venue
{
public int Id { get; set; }
[Required]
[MaxLength(50)]
public string Name { get; set; }
public int? ConferenceId { get; set; }
public Trip Conference { get; set; }
public int? LocationId { get; set; }
public City City { get; set; }
}
public class City
{
public int Id { get; set; }
[Required]
[MaxLength(50)]
public string Name { get; set; }
public ICollection<Conference> Conferences { get; set; }
public ICollection<Venue> Venues { get; set; }
}
In the repository, I have a method that returns the conferences and the related entities (City and Venues):
public IEnumerable<Conference> GetAllConferences()
{
return _context.Conferences
.Include(t => t.Venues)
.Include(t => t.City)
.ToList();
}
In the controller I need to use the following code to return all the results:
var conferences = _repository.GetAllConferences();
if (conferences.Any())
{
var conferenceListVm = trips.ToConferenceVmList();
//Without setting the FK references to null, I can return only the first result of the collection
foreach (var vm in conferenceListVm)
{
foreach (var pm in vm.PoinOfInterests)
{
pm.Trip = null;
}
vm.Location.Conferences = null;
vm.Location.Venues = null;
}
return Ok(conferenceListVm);
}
public static ConferenceViewModel ToConferenceVm(this Conference conference)
{
var confVm = new ConferenceViewModel();
confVm.Name = conference.Name;
confVm.City = conference.City;
confVm.Venues = conference.Venues;
return tripVm;
}
public static IEnumerable<ConferenceViewModel> ToConferenceVmList(this IEnumerable<Conference> conferences)
{
return conferences.Select(c => c.ToConferenceVm()).ToList();
}

Entity Framework reference property

I am working with Entity Framework 6.
I am working with 2 classes:
public partial class StateProvince
{
public StateProvince()
{
Addresses = new HashSet<Address>();
}
public int StateProvinceID { get; set; }
public string StateProvinceCode { get; set; }
public string CountryRegionCode { get; set; }
public bool IsOnlyStateProvinceFlag { get; set; }
public string Name { get; set; }
public int TerritoryID { get; set; }
public Guid rowguid { get; set; }
public DateTime ModifiedDate { get; set; }
public ICollection<Address> Addresses { get; set; }
public CountryRegion CountryRegion { get; set; }
}
public partial class CountryRegion
{
public CountryRegion()
{
StateProvinces = new HashSet<StateProvinceTlb>();
}
public string CountryRegionCode { get; set; }
public string Name { get; set; }
public DateTime ModifiedDate { get; set; }
public virtual ICollection<StateProvince> StateProvinces { get; set;}
}
I would like to be able to run a query that would return a list of StateProvince, but also include the name from CountryRegion. The idea is that on an edit screen, the user will select, or edit the CountryRegionCode, but the Name will display beside it in a none editable field just for reference.
I tried adding property as a none mapped field to StateProvince and referencing the property on CountryRegion, like below:
[NotMapped]
public string CountryName
{
get{ return CountryRegion.Name;}
}
but the problem with this is the CountryRegion has to be loaded in order for that to work, and my goal is to not have to load the entire CountryRegion object.
I've also tried to set it in my query like this:
List<StateProvince> statP = context.StateProvinces.Select(s => new StateProvince() {s, CountryName = context.CountryRegions.Where(x => x.CountryRegionCode == s.CountryRegionCode).Select(x => x.Name).FirstOrDefault() }).ToList();
but this doesn't work because the object returned is comprised of a StateProvince object and a separate CountryName property.
I've even tried setting each of the fields individually like:
List<StateProvince> statP = context.StateProvinces.Select(s => new StateProvince() { Name = s.Name, TerritoryID = s.TerritoryID, rowguid = s.rowguid, ModifiedDate = s.ModifiedDate, Addresses=s.Addresses, CountryRegion=s.CountryRegion, CountryName = context.CountryRegions.Where(x => x.CountryRegionCode == s.CountryRegionCode).Select(x => x.Name).FirstOrDefault() }).ToList();
But this again causes the entire CountryRegion object to load, and if I leave those properties out, an exception is thrown. Also, for larger entities this will be hard to maintain.
The TLDR; version of this: Is there a way in Entity Frameworks to have a class mapped to one table, but have a property on that class that references a property on another table without having to retrieve everything on the child table?
I've searched and searched and can't really find much covering this specific kinda of scenario. I'm fairly new to Entity Framework, and I feel like I'm missing something obvious. Any help would be greatly appreciated!!
SOLUTION
This is what I've come up with to solve the issue.
First, I split the CountryRegion table into two separate classes
public partial class CountryRegionHeader
{
public CountryRegionHeader()
{
StateProvinces = new HashSet<StateProvinceTlb>();
}
public string CountryRegionCode { get; set; }
public string Name { get; set; }
}
public partial class CountryRegionDetail
{
public CountryRegionDetail()
{
StateProvinces = new HashSet<StateProvinceTlb>();
}
public string CountryRegionCode { get; set; }
public DateTime ModifiedDate { get; set; }
public virtual ICollection<StateProvince> StateProvinces { get; set;}
public virtual CountryRegion CountryRegion {get;set;}
}
I then add the properties for the new classes to my StateProvince class
[ForeignKey("CountryRegionCode)]
public CountryRegionHeader CountryRegionHeader {get;set;}
[ForeignKey("CountryRegionCode)]
public CountryRegionDetail CountryRegionDetail {get;set;}
I then add the DBSets to my model context for CountryRegionHeader and CountryRegionDetail and tie them together using the fluent API in the OnModelCreating method
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<CountryRegionHeader>()
.HasRequired(e => e.CountryRegionDetail)
.WithRequiredPrincipal();
}
In addition to this, I've created another class just called CountryRegion which has all of the properties from both the Header and Detail as well as the Header and Detail object themselves. The properties actually point back to the header and detail. This really isn't necessary, but it makes the code cleaner and easier to use. Also, when sending the data down to a web client I can just serialize the CountryRegion object and exclude the Header and Detail object. So basically my CountryRegion class looks like this:
public Class CountryRegion
{
public CountryRegionHeader Header;
public CountryRegionDetail Detail;
public CountryRegionCode
{
//need some special logic here for the key since both Header or
//Detail share the primary key and both may not be loaded
get
{
if (Header != null)
return Header.CountryRegionCode;
else
return Detail.CountryRegionCode;
}
set
{
if (Header != null) Header.CountryRegionCode = value;
if (Detail != null) Detail.CountryRegionCode = value;
}
}
public string Name
{
get
{
return Header.Name;
}
set
{
Header.Name = value;
}
}
public DateTime ModifiedDate
{
get
{
return Detail.ModifiedDate ;
}
set
{
Detail.ModifiedDate = value;
}
}
public virtual ICollection<StateProvince> StateProvinces
{
get
{
return Detail.StateProvinces ;
}
set
{
Detail.StateProvinces = value;
}
}
}
So, Now When I query I can do something like:
List<StateProvince> query = db.StateProvince.Include(o=>o.CountryRegionHeader).ToList();
And I only retrieve the data I need without retrieving the entire CountryRegion record
Also, If I'm working with just the CountryRegion, I can query like this:
List<CountryRegion> query = (from a in db.CountryRegionHeader join b in db.CountryRegionDetail on a.CountryRegionCode equals b.CountryRegionCode select new Employee(){Header = a, Detail = b}).ToList();
SOLUTION
This is what I've come up with to solve the issue.
First, I split the CountryRegion table into two separate classes
public partial class CountryRegionHeader
{
public CountryRegionHeader()
{
StateProvinces = new HashSet<StateProvinceTlb>();
}
public string CountryRegionCode { get; set; }
public string Name { get; set; }
}
public partial class CountryRegionDetail
{
public CountryRegionDetail()
{
StateProvinces = new HashSet<StateProvinceTlb>();
}
public string CountryRegionCode { get; set; }
public DateTime ModifiedDate { get; set; }
public virtual ICollection<StateProvince> StateProvinces { get; set;}
pubic virtual CountryRegion CountryRegion {get;set;}
}
I then add the properties for the new classes to my StateProvince class
[ForeignKey("CountryRegionCode)]
public CountryRegionHeader CountryRegionHeader {get;set;}
[ForeignKey("CountryRegionCode)]
public CountryRegionDetail CountryRegionDetail {get;set;}
I then add the DBSets to my model context for CountryRegionHeader and CountryRegionDetail and tie them together using the fluent API in the OnModelCreating method
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<CountryRegionHeader>()
.HasRequired(e => e.CountryRegionDetail)
.WithRequiredPrincipal();
}
In addition to this, I've created another class just called CountryRegion which has all of the properties from both the Header and Detail as well as the Header and Detail object themselves. The properties actually point back to the header and detail. This really isn't necessary, but it makes the code cleaner and easier to use. Also, when sending the data down to a web client I can just serialize the CountryRegion object and exclude the Header and Detail object. So basically my CountryRegion class looks like this:
public Class CountryRegion
{
public CountryRegionHeader Header;
public CountryRegionDetail Detail;
public CountryRegionCode
{
//need some special logic here for the key since both Header or
//Detail share the primary key and both may not be loaded
get
{
if (Header != null)
return Header.CountryRegionCode;
else
return Detail.CountryRegionCode;
}
set
{
if (Header != null) Header.CountryRegionCode = value;
if (Detail != null) Detail.CountryRegionCode = value;
}
}
public string Name
{
get
{
return Header.Name;
}
set
{
Header.Name = value;
}
}
public DateTime ModifiedDate
{
get
{
return Detail.ModifiedDate ;
}
set
{
Detail.ModifiedDate = value;
}
}
public virtual ICollection<StateProvince> StateProvinces
{
get
{
return Detail.StateProvinces ;
}
set
{
Detail.StateProvinces = value;
}
}
}
So, Now When I query I can do something like:
List<StateProvince> query = db.StateProvince.Include(o=>o.CountryRegionHeader).ToList();
And I only retrieve the data I need without retrieving the entire CountryRegion record
Also, If I'm working with just the CountryRegion, I can query like this:
List<CountryRegion> query = (from a in db.CountryRegionHeader join b in db.CountryRegionDetail on a.CountryRegionCode equals b.CountryRegionCode select new Employee(){Header = a, Detail = b}).ToList();
One way to achieve this is to add a computed column on your database that gives you the CountryRegion name on your StateProvince.
With this all you have to do is to request the StateProvince table and your database server will give you the relevant associated CountryRegion name.
Edit
After your comment I had another idea.
Create a class for your usage :
public class StateProvinceEdition : StateProvince
{
public string CountryRegionName { get; set; }
public StateProvinceEdition(StateProvince stateProvince, string countryRegionName)
{
this.StateProvinceID = stateProvince.StateProvinceID;
// And so on ...
// Adding country region name
this.CountryRegionName = countryRegionName;
}
}
Then you need to project your query result into your object using Linq :
List<StateProvinceEdition> statP = context.StateProvinces.Select(s => new StateProvince(s, s.CountryRegion.Name)).ToList();
I do not have a database to test it upon so if EF throws an exception regarding the constructor, try to switch the Select and ToList statements to first load objects from the database and then project the result in the custom class.
Second edit
Similar to the first idea, you can create a view in your database for your purpose and then use Entity Framework to query this view. With this solution you do not need to change your database other than adding a view.

What's the proper way to get data using Entity Framework so you can navigate through objects?

I have a .Net 4.5 MVC 5 database first project that I'm playing around with. There's a data access layer (Entity Framework 6), a business logic layer and the MVC layer.
If I have an object with relationships in the data layer:
namespace DataAccess
{
public class Course
{
public int CourseID { get; set; }
public string Title { get; set; }
public ICollection<Lecture> Lectures { get; set; }
public ICollection<Tutor> Tutors { get; set; }
}
public class Lecture
{
public int LectureID { get; set; }
public string Title { get; set; }
public DateTime Date { get; set; }
public ICollection<Student> Students { get; set; }
}
public class Tutor
{
public int TutorID { get; set; }
public string Name { get; set; }
}
public class Student
{
public int StudentID { get; set; }
public string Name { get; set; }
}
}
And in my business logic layer I have a method that gets courses:
namespace BusinessLogic
{
public static IEnumerable<Course> GetCourses()
{
using (var db = new MyEntities())
{
return db.Courses.Include("Lectures").Include("Lectures.Students").Include("Tutors").ToList();
}
}
}
And I get the data using my controller like this:
public class HomeController : Controller
{
public ActionResult Index()
{
var courses = BusinessLogic.GetCourses();
return View(courses);
}
}
Why is it, when I query my data in the Razor view like this:
var numLectures = courses.Lectures.Count;
var numStudents = courses.Lectures.Students.Count;
var tutorName = courses.Tutors.LastOrDefault().Name;
I get the application error System.ObjectDisposedException: The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.
I know the connection is disposed after the using statement has finished and that .ToList() will let me navigate the courses object, but how do I navigate the objects inside each course (i.e. lectures, students, tutors etc.)?
Your navigation properties need to be declared as virtual:
namespace DataAccess
{
public class Course
{
public int CourseID { get; set; }
public string Title { get; set; }
public virtual ICollection<Lecture> Lectures { get; set; }
public virtual ICollection<Tutor> Tutors { get; set; }
}
public class Lecture
{
public int LectureID { get; set; }
public string Title { get; set; }
public DateTime Date { get; set; }
public virtual ICollection<Student> Students { get; set; }
}
...
}
When these lazy loadable properties are not marked as virtual, the EF dynamic proxies cannot override them and you will never be able to navigate from one entity to a (set of) another.
Another bit of advice: use the strongly-typed .Include when eager loading:
namespace BusinessLogic
{
public static IEnumerable<Course> GetCourses()
{
using (var db = new MyEntities())
{
return db.Courses
.Include(x => x.Lectures.Select(y => y.Students))
.Include(x => x.Tutors)
.ToList();
}
}
}
I think the problem is because one (or more than one) property that you are calling in your View is (are) not included in your query. Make sure you are including all the navigation properties you need in the view. Try with this query:
using (var db = new MyEntities())
{
return db.Courses.db.Courses.Include(c=>c.Lectures.Select(l=>l.Students)).Include(c=>c.Tutors‌​).ToList()
}
If you need to add another relative property that you use in your View, then add another Include call for that property.
Another thing, when you need to eager load two levels (like Lectures.Students), you don't need to add a Include call for each level, with the call that you do for the second level is enough to include both. Could be this way:
.Include("Lectures.Students") // as you did it
Or:
.Include(c=>c.Lectures.Select(l=>l.Students))

Categories