MVC5 Entity Framework Learning reading related data

Source: Internet
Author: User
Tags actionlink

The school data model was completed in the previous article, and you will then learn how to read and display the relevant data-this is the data that the Entity Framework loads into the navigation properties.

is done after the




delay, pre-and display loading related data

The Entity Framework can load data into the navigation properties of entities in several ways

    • Deferred load (lazy loading) when the entity is read for the first time, the relevant data is not retrieved. However, when you first access the navigation property, the data required for that navigation property is automatically loaded. This is the result of sending multiple query statements to the database-one time to read the entity itself, followed by each data associated with the entity being retrieved. The DbContext class defaults to starting a lazy load.


    • Preload (Eager Loading) loads the data associated with the entity while it is being read. This is usually to retrieve all the required data in a single connection query, and you can use the Include method to specify whether to use preload.


    • Explicit loading (Explicit Loading) is similar to lazy loading, but needs to be displayed in code that indicates the data to be retrieved. When you access a navigation property, it does not automatically load, you need to get the entity's Object state Manager entry and call the collection's Collection.load method or the Reference.load method with a single property to manually load the relevant data. (In the example below, if you want to load the Administrator navigation property, you need to replace Collection (x = x.courses) with reference (x = x.administrator) Typically you should use display loading in case of disabling lazy loading.


Because lazy loading and explicit loading do not immediately retrieve the value of the property, they are also referred to as deferred loading (deferred loading.).

Performance Considerations

If you know that you need to load relevant data for each entity being retrieved, preload typically has the best performance, because a single query is often more efficient than querying for each entity separately. For example, in the example above, assuming that each department has 10 related course, preloading only needs a single connection query to retrieve all the data once and for all, while both lazy loading and explicit loading require 11 queries 11 round-trip to the database to get the same result. In the case of high latency, additional round trips are very detrimental to performance.

On the other hand, delay loading is more efficient in some cases. Preloading may generate complex connection queries that SQL Server cannot handle efficiently. Or if you're accessing the navigation properties of a collection or subset of entities you're working on, lazy loading is more efficient because preloading retrieves data that you don't need. If performance is critical, then you'd better test both methods to choose the one that performs more efficiently.

Lazy loading masks The code that causes performance problems. For example, code that does not specify pre-or explicit loading but handles high concurrency for multiple navigation properties in each iteration can be inefficient (because there will be a large number of database round trips). A well-behaved application that uses On-premise SQL Server in a development environment may cause performance problems when deployed to Windows Azure SQL database due to increased latency and lazy loading. You should use a real test load to analyze database queries to determine whether to use lazy loading.

to disable lazy loading before serialization

If you enable lazy loading during serialization, you will be querying much more data than expected. Serialization typically accesses each property of an instance, while property access triggers a lazy load, and these lazy-loaded entities are serialized, and then the serialization process accesses every property of the deferred-loaded entity, which can lead to more lazy loading and serialization. To prevent this runaway chain reaction, you need to disable lazy loading before serializing the entity.

Serialization is also cross-complex by using the proxy class of the Entity Framework.

One way to avoid serialization problems is to serialize data transfer objects (DTOS) instead of entity objects.

If you are not using DTOs, you can disable lazy loading and avoid proxy problems by using disable proxy creation.

Here are some other ways to disable lazy loading:

    • Omit the virtual keyword for a specific navigation property when declaring
    • For all navigation properties, set lazyloadingenabled to False, placing the following code in the constructor of the context class

      This. configuration.lazyloadingenabled = false;

Create a courses page and display the department name

The course entity contains a navigation property that contains the department entity, and if you want to display the assigned department name in the course list, You need to get the name attribute in the Department entity in the Course.department navigation property.

Using the MVC 5 controller with views, the using Entity Framework framework creates a new controller named Coursecontroller for the course entity type, just as it did before to create a controller for student


Open Controllers\coursecontroller.cs, view the index method

        Public ActionResult Index ()        {            var courses = db. Courses.include (c = c.department);            Return View (courses. ToList ());        }
You can see that the framework uses the include method to specify the department navigation property as preloaded.

Open views\course\index.cshtml and replace it with the following code

@model ienumerable<contosouniversity.models.course>@{viewbag.title = "Courses";} The following changes are made to the framework code:

    • Change title from index to course
    • Added a number column to display the value of the CourseID property by default, the framework does not generate code that displays the primary key because it is usually meaningless to the end user. But in this case, you want to show it
    • Move the Department column to the right display and modify its caption. The framework correctly selects its Name property from the department entity and displays it, but in the course page, the column header should appear as department instead of the name

Note For the Department column, the framework code shows the name property of the department entity loaded into the Department navigation property.

<td>    @Html. displayfor (ModelItem = Item. Department.name) </td>
Run the project, select the Courses tab, view the data


Create instructors page to display Courses and enrollments

In this section you will create a controller for the instructor entity and try to display the instructors


This page reads and displays related data in the following ways:

    • The instructor list shows the related data in the OfficeAssignment entity, with a one-to-one or zero relationship between the instructor and OfficeAssignment entities, which you can preload with the officeassignment entity. As mentioned earlier, preload is more efficient when you need to retrieve the relevant data for all rows in the primary table. In this example, you want to show office assignments for all instructor.
    • When the user chooses a instructor, the related course entities are also displayed, and the instructor and course entities are many-to-many relationships. You can use preload for course entities and related department entities. In this case, lazy loading can be more efficient because you only need course information for those instructor that have been selected. However, in this example, only the navigation properties of the navigation property entity are used to preload.
    • When the user chooses a gate course, the data in the related enrollments entity is displayed, and the course and enrollment entities are one-to-many relationships. You will use explicit loading for enrollment entities and related student entities (display loading is not required because lazy loading is enabled, this is a demonstration only).

Create a view model for the instructor index view

The instructors page shows three different tables, and you create a view model with three attributes, each containing the data needed for a table.

Open the ViewModels folder, create the InstructorIndexData.cs class, and replace it with the following code

Using system.collections.generic;using contosouniversity.models;namespace contosouniversity.viewmodels{    public class Instructorindexdata    {public        ienumerable<instructor> instructors {get; set;}        Public ienumerable<course> Courses {get; set;}        Public ienumerable<enrollment> enrollments {get; set;}}    }
creating Instructor controllers and views

Create a Instructorcontroller controller using the EF read/write actions framework


Open Controllers\instructorcontroller.cs, add ViewModels namespace

Using Contosouniversity.viewmodels;
The framework code in the Index method specifies that only pre-loading is used for officeassignment navigation properties

Public ActionResult Index () {    var instructors = db. Instructors.include (i = i.officeassignment);    Return View (instructors. ToList ());}
Replace the index method with the following code to load additional related data and pass it to the view model

Public ActionResult Index (int? id, int courseid) {    var viewModel = new Instructorindexdata ();    Viewmodel.instructors = db. Instructors        . Include (i = i.officeassignment)        . Include (i = i.courses.select (c = c.department))        . (i = i.lastname);    if (id! = null)    {        Viewbag.instructorid = ID. Value;        viewmodel.courses = ViewModel.Instructors.Where (            i = i.id = = ID. Value). Single (). Courses;    }    if (CourseID! = null)    {        Viewbag.courseid = Courseid.value;        viewmodel.enrollments = ViewModel.Courses.Where (            x = = X.courseid = = CourseID). Single (). enrollments;    }    Return View (ViewModel);}

The method receives an optional route parameter (ID) and a query string parameter (CourseID) to provide the ID value of the selected instructor and course, and to pass the data required for the view. The parameters are provided by the Select link on the page.

The code above first creates an instance of the view model and puts the instructors list in it, which specifies that the instructor.officeassignment and instructor.courses navigation properties use preload.

var ViewModel = new Instructorindexdata (); viewmodel.instructors = db. Instructors    . Include (i = i.officeassignment)    . Include (i = i.courses.select (c = c.department))     . (i = i.lastname);
The second include method loads the course entity and pre-loads the Course.department navigation properties for each loaded course entity.

. Include (i = i.courses.select (c = c.department))
As mentioned earlier, preload is not required, but it is used here to improve program performance. Because views always require officeassgnment entities, it is more efficient to retrieve them in the same query. When a instructor is selected in the page, the course entity is required, so preload is more efficient than lazy loading only when the selected course are often displayed in the page.

If a instructor ID is selected, the selected instructor is retrieved from the instructor list in the view model, and the courses entity of the view model is passed instructor The courses property of the course navigation property to load.

if (id! = null) {    Viewbag.instructorid = ID. Value;    viewmodel.courses = ViewModel.Instructors.Where (i = i.id = = ID. Value). Single (). Courses;}
The Where method returns a collection, but in this case, the method returns only one instructor entity by passing the parameter. The single method transforms the collection into a instructor entity that enables you to access the courses property of the entity.

When you know that the collection contains only one element, you can use the single method of the collection. When the collection is empty or contains multiple elements, the single method throws an exception. Another option is to use Singleordefault, which returns a default value if the collection is empty. However, using Singleordefault in this example still throws an exception (querying the courses property in a null reference), but the exception information does not explicitly indicate the cause of the problem. When you call the single method, you can also direct it as a where condition instead of calling the where and single method separately:

. Single (i = I.id = = ID. Value)
Instead of:

. Where (I = I.id = = ID. Value). Single ()

Next, if you select a door course, the course is retrieved from the course list in the view model. The enrollments entity of the view model is then loaded through the enrollments property of the enrollments navigation property of the course.

    if (CourseID! = null)    {        Viewbag.courseid = Courseid.value;        viewmodel.enrollments = ViewModel.Courses.Where (            x = = X.courseid = = CourseID). Single (). enrollments;    }

Modify the Instructor Index view

Open views\instructor\index.cshtml and replace it with the following code

@model contosouniversity.viewmodels.instructorindexdata@{viewbag.title = "Instructors";} Changes made to the code:

    • Change the view model class to Instructorindexdata
    • Change the title to instructors
    • Add the Office column so that it is in item. Officeassignent display Item.OfficeAssignment.Location when not empty (because they are a pair of 0 or one relationship, there may not be a related officeassignment entity)

      <td>     @if (item. OfficeAssignment! = null)     {         @item. Officeassignment.location      

    • Dynamically adds the class= "success" style to the selected instructor TR element by using bootstrap to set the background color for the selected row

      String selectedrow = ""; if (item. Instructorid = = Viewbag.instructorid) {     

    • Add a new ActionLink, you can send the selected instructor ID to the index method

Run the project, select the Instructors tab, and the Location property value for the related officeassignment entity is displayed on the page, and nothing is displayed if the OfficeAssignment entity is empty.


Open views\instructor\index.cshtml and add the following code after the table element end tag to display the list of course for the selected instructor

@if (model.courses! = null) {The above code displays the course list by reading the course property in the view model, and it also provides a select link to pass the ID of the selected course to the index method.

Run the project, select a instructor, and you can see that the page shows the course and course assigned to the selected instructor Department


Add the following code again after the code you just added, to show the list of student that took the selected course

@if (model.enrollments! = null) {    
The above code reads the Enrollments property in the view model to display those student lists that take the selected course

Run the project, select a instructor, and in the Select a door course, you can see the student list of the course that is displayed on the page


Specifies that the display load

Open NstructorController.cs to see how the index method obtains the enrollment list of the selected course.

    if (CourseID! = null)    {        Viewbag.courseid = Courseid.value;        viewmodel.enrollments = ViewModel.Courses.Where (            x = = X.courseid = = CourseID). Single (). enrollments;    }

When retrieving the instructor list, you specify a preload for the courses navigation property and the Department property for each course, and then pass the courses collection to the view model. Next you can access the enrollments navigation properties for each entity in the collection. Because you did not specify pre-loading for the Course.enrollments navigation property, the data in that property is rendered in the page with lazy loading.

If you disable lazy loading without modifying any code, the enrollments property value will be null regardless of how much enrollment the course actually contains. In this case, to load the enrollments property, you must specify that it is preloaded or explicitly loaded. You already know how to use pre-loading, in order to demonstrate explicit loading, replace the index method with the following code

Public ActionResult Index (int? id, int courseid) {var viewModel = new Instructorindexdata (); Viewmodel.instructors = db. Instructors. Include (i = i.officeassignment). Include (i = i.courses.select (c = c.department)).    (i = i.lastname); if (id! = NULL) {Viewbag.instructorid = ID.        Value; viewmodel.courses = ViewModel.Instructors.Where (i = i.id = = ID. Value). Single ().    Courses;        } if (CourseID! = null) {Viewbag.courseid = Courseid.value; Lazy Loading//viewmodel.enrollments = ViewModel.Courses.Where (//x = X.courseid = = CourseID). Single ().        enrollments; Explicit loading var selectedcourse = viewModel.Courses.Where (x = = X.courseid = CourseID).        Single (); Db. Entry (Selectedcourse). Collection (x = x.enrollments).        Load (); foreach (Enrollment enrollment in selectedcourse.enrollments) {db. Entry (Enrollment). ReferenCE (x = x.student).        Load ();    } viewmodel.enrollments = selectedcourse.enrollments; } return View (ViewModel);}
Enrollments navigation properties that load course are displayed after the course entity is obtained

Db. Entry (Selectedcourse). Collection (x = x.enrollments). Load ();
The student entity associated with each enrollment entity is then displayed

Db. Entry (Enrollment). Reference (x = x.student). Load ();
Note that you use the collection property to load collection properties, but for properties that contain only one entity, you should use the Reference property.

Run the project, you will find that the page rendering data is not a different place, but in fact we have changed the way the data retrieved.

Original: Reading related Data with the Entity Framework in an ASP. NET MVC Application

Welcome reprint, please indicate the source of the article: http://blog.csdn.net/johnsonblog/article/details/39136963

Also everyone a healthy network environment, from you and I start

The END

MVC5 Entity Framework Learning reading related data

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.