Entity Framework Core series data query Tutorial -6-

Entity Framework Core queries

Entity Framework Core query with the same query EF 6.x, but a more optimized SQL query, and C # / VB.NET LINQ function can be included in the query to an entity.
Entity Framework Core allows you to use navigation properties in the model to load related entities. There are three common O / RM mode may be used to load the associated data:

  • Eager loading (pre-load): indicates load the associated data from the database, as part of the initial query.
  • Explicit loading (explicit load): later said explicitly load the associated data from the database.
  • Lazy loading (loading delay): indicates when accessing the navigation attributes transparently load the associated data from the database.

Access LINQ-to-Entities chapter for more information about the Entity Framework query-based.
Here you will learn query Entity Framework Core new features introduced.

Query C # / VB.NET function

EF Core with new features in LINQ-to-Entities, we can include C # or VB.NET function in a query. This EF 6 is not possible.

private static void Main(string[] args)
{
    var context = new SchoolContext();
    var studentsWithSameName = context.Students
                                      .Where(s => s.FirstName == GetName())
                                      .ToList();
}

public static string GetName() {
    return "Bill";
}

In the above L2E query, we included a Where clause in the GetName () C # function. This will execute the following query in the database:

exec sp_executesql N'SELECT [s].[StudentId], [s].[DoB], [s].[FirstName], 
    [s].[GradeId], [s].[LastName], [s].[MiddleName]
FROM [Students] AS [s]
WHERE [s].[FirstName] = @__GetName_0',N'@__GetName_0 nvarchar(4000)',
    @__GetName_0=N'Bill'
Go

Eager Loading preloaded

Entity Framework Core supports the use Include () extension method and projection queries to quickly load the same EF 6 related entities. In addition, it provides ThenInclude () extension method to load multiple levels of related entities. (EF 6 does not support ThenInclude () method.)

Include:

Different from the EF 6, we can () method will be specified as parameters in the lambda expression Include, navigation attributes to specify, as shown below.

var context = new SchoolContext();
var studentWithGrade = context.Students
                           .Where(s => s.FirstName == "Bill")
                           .Include(s => s.Grade)
                           .FirstOrDefault();

In the example above, .Include (s => s.Grade) passing lambda expression s => s.Grade, in order to specify a reference attribute, which is loaded with data from the database entity Student together in a single SQL query. The above query execute the following SQL query in the database.

SELECT TOP(1) [s].[StudentId], [s].[DoB], [s].[FirstName], [s].[GradeId],[s].[LastName], 
        [s].[MiddleName], [s.Grade].[GradeId], [s.Grade].[GradeName], [s.Grade].[Section]
FROM [Students] AS [s]
LEFT JOIN [Grades] AS [s.Grade] ON [s].[GradeId] = [s.Grade].[GradeId]
WHERE [s].[FirstName] = N'Bill'

We can also () method in the name as the attribute string Include, 6 in the same EF.

var context = new SchoolContext();
var studentWithGrade = context.Students
                        .Where(s => s.FirstName == "Bill")
                        .Include("Grade")
                        .FirstOrDefault();

We do not recommend using the above example, because the name is misspelled or if the property does not exist, a runtime exception is thrown. Always use Include () method for lambda expressions, so that can detect errors at compile time.

The Include () extension method may also be used after FromSql () method as follows.

var context = new SchoolContext();
var studentWithGrade = context.Students
                        .FromSql("Select * from Students where FirstName ='Bill'")
                        .Include(s => s.Grade)
                        .FirstOrDefault();      

Note: You can not use Include () extension method after DbSet.Find () method. E.g. You can not use context.Students.Find (1) .Include () in EF Core 2.0 in. In future releases this may be possible.

Multiple use the Include () method to load the same entity more navigation attributes. For example, the following code loads and StudentCourses Grade Student's related entities.

var context = new SchoolContext();
var studentWithGrade = context.Students.Where(s => s.FirstName == "Bill")
                        .Include(s => s.Grade)
                        .Include(s => s.StudentCourses)
                        .FirstOrDefault();

The above query will execute two SQL queries in a single database round trip.

SELECT TOP(1) [s].[StudentId], [s].[DoB], [s].[FirstName], [s].[GradeId], [s].[LastName], 
        [s].[MiddleName], [s.Grade].[GradeId], [s.Grade].[GradeName], [s.Grade].[Section]
FROM [Students] AS [s]
LEFT JOIN [Grades] AS [s.Grade] ON [s].[GradeId] = [s.Grade].[GradeId]
WHERE [s].[FirstName] = N'Bill'
ORDER BY [s].[StudentId]
Go

SELECT [s.StudentCourses].[StudentId], [s.StudentCourses].[CourseId]
FROM [StudentCourses] AS [s.StudentCourses]
INNER JOIN (
    SELECT DISTINCT [t].*
    FROM (
        SELECT TOP(1) [s0].[StudentId]
        FROM [Students] AS [s0]
        LEFT JOIN [Grades] AS [s.Grade0] ON [s0].[GradeId] = [s.Grade0].[GradeId]
        WHERE [s0].[FirstName] = N'Bill'
        ORDER BY [s0].[StudentId]
    ) AS [t]
) AS [t0] ON [s.StudentCourses].[StudentId] = [t0].[StudentId]
ORDER BY [t0].[StudentId]
Go

ThenInclude

EF Core introduces new ThenInclude () extension method to load a plurality of levels associated entities. Consider the following example:

var context = new SchoolContext();
var student = context.Students.Where(s => s.FirstName == "Bill")
                        .Include(s => s.Grade)
                            .ThenInclude(g => g.Teachers)
                        .FirstOrDefault();

In the example above, .Include (s => s.Grade) loaded navigation properties Grade Student entity. .ThenInclude (g => g.Teachers) loaded Grade Teacher entity attribute set. ThenInclude method must be called after the Include method. The above code will execute the following SQL query in the database.

SELECT TOP(1) [s].[StudentId], [s].[DoB], [s].[FirstName], [s].[GradeId], [s].[LastName],
         [s].[MiddleName], [s.Grade].[GradeId], [s.Grade].[GradeName], [s.Grade].[Section]
FROM [Students] AS [s]
LEFT JOIN [Grades] AS [s.Grade] ON [s].[GradeId] = [s.Grade].[GradeId]
WHERE [s].[FirstName] = N'Bill'
ORDER BY [s.Grade].[GradeId]
Go

SELECT [s.Grade.Teachers].[TeacherId], [s.Grade.Teachers].[GradeId], [s.Grade.Teachers].[Name]
FROM [Teachers] AS [s.Grade.Teachers]
INNER JOIN (
    SELECT DISTINCT [t].*
    FROM (
        SELECT TOP(1) [s.Grade0].[GradeId]
        FROM [Students] AS [s0]
        LEFT JOIN [Grades] AS [s.Grade0] ON [s0].[GradeId] = [s.Grade0].[GradeId]
        WHERE [s0].[FirstName] = N'Bill'
        ORDER BY [s.Grade0].[GradeId]
    ) AS [t]
) AS [t0] ON [s.Grade.Teachers].[GradeId] = [t0].[GradeId]
ORDER BY [t0].[GradeId]
go

Projection Query (query projection)

We can also query instead of Include () or ThenInclude () method to load multiple related entities by using the projector. The following example demonstrates used to load the "student", projection query "year" and "teacher" entity.

var context = new SchoolContext();
var stud = context.Students.Where(s => s.FirstName == "Bill")
                        .Select(s => new
                        {
                            Student = s,
                            Grade = s.Grade,
                            GradeTeachers = s.Grade.Teachers
                        })
                        .FirstOrDefault();

In the example above, .Select extension method used in results include Student, Grade and Teacher entity. This will perform the above ThenInclude () method of the same SQL query.

About lazy loading (Lazy Loading) and explicitly loaded (Explicit Loading) EF Core 3.1 has support for the original 2.0 version is out of date, you can refer to the official document:

Reference: https://docs.microsoft.com/en-us/ef/core/querying/related-data

Guess you like

Origin www.cnblogs.com/AlexanderZhao/p/12289193.html
Recommended