Entity Frameworkのコア系列データクエリチュートリアル-6-

Entity Frameworkのコアのクエリ

同じクエリEF 6.xのとEntity Frameworkのコア・クエリが、より最適化されたSQLクエリ、およびC#/ VB.NET LINQ機能は、エンティティにクエリに含めることができます。
Entity Frameworkのコアを使用すると、関連するエンティティをロードするためのモデルでナビゲーションプロパティを使用することができます。3つの一般的なO / RMモードは、関連するデータをロードするために使用することができるがあります。

  • イーガーローディング(前負荷):最初のクエリの一部として、データベースから関連するデータをロード示します。
  • 明示的ローディング(明示的な負荷):後明示的データベースから関連するデータをロードすると述べました。
  • レイジーローディング(装填遅延):透過データベースから関連データをロード属性ナビゲーションにアクセスする場合を示しています。

アクセスLINQツーエンティティ Entity Frameworkのクエリベースの詳細については、章を参照してください。
ここでは、導入されたクエリEntity Frameworkのコアの新機能を学習します。

クエリC#/ VB.NETの機能

LINQツーエンティティの新機能を備えたEFコア、我々はクエリでC#やVB.NETの機能を含めることができます。このEF 6はできません。

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";
}

上記L2Eクエリでは、我々は、関連項目GetName()C#関数でWhere句が含まれています。これは、データベースで次のクエリを実行します:

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

イーガーロードプリロード

Entity Frameworkのコアを使用すると、()拡張メソッドと投影クエリがすぐに同じEF 6関連するエンティティをロードするために含めサポートしています。また、関連するエンティティの複数のレベルをロードするThenInclude()拡張メソッドを提供します。(EF 6はThenInclude()メソッドをサポートしません。)

含める:

EF 6とは異なり、我々は()メソッドは、ラムダ式のパラメータとして含める指定されることができ、ナビゲーションは以下に示すように、指定する属性。

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

.INCLUDE(S​​ => s.Grade)通過ラムダ式S => s.Grade、上記の例では、単一のSQLクエリで一緒にデータベース・エンティティ学生からデータがロードされた参照属性を指定するためです。上記のクエリは、データベースに次のSQLクエリを実行します。

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'

私たちは、属性文字列は、同じEF 6を含めると名前でも()メソッドすることができます。

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

名前のスペルが間違っているか、プロパティが存在しない場合は、実行時例外がスローされますので、我々は、上記の例を使用することはお勧めしません。それはコンパイル時にエラーを検出することができますので、必ず、ラムダ式の()メソッドを含める使用しています。

次のように含める()拡張メソッドもFromSql()メソッドの後に使用することができます。

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

注:DbSet.Find()メソッドの後に含める()拡張メソッドを使用することはできません。たとえば。あなたはcontext.Students.Find(1).INCLUDE()EFコア2.0の中で使用することはできません。将来のリリースでは、これは可能かもしれません。

含める()メソッドを複数使用することは、同じ実体複数のナビゲーション属性をロードします。たとえば、次のコードのロードとStudentCoursesグレードスチューデント関連するエンティティ。

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

上記のクエリは、単一のデータベース・ラウンドトリップで2つのSQLクエリを実行します。

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コアは、エンティティに関連する複数のレベルをロードする新しいThenInclude()拡張メソッドを導入します。次の例を考えてみます。

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

上記の例では、.INCLUDEは(S => s.Grade)ナビゲーションプロパティグレード学生エンティティをロードしました。.ThenInclude(G => g.Teachers)グレード教師エンティティ属性のセットをロードしました。ThenInclude方法は含めるメソッドの後に呼び出さなければなりません。上記のコードは、データベースに次のSQLクエリを実行します。

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

投影クエリ(クエリ投影)

我々はまた、クエリの代わりに含めることができます()またはThenInclude()メソッドは、プロジェクターを使用して、複数の関連するエンティティをロードします。次の例では、「学生」、投影クエリ「年」と「先生」エンティティをロードするために使用示しています。

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();

上記の例では、結果に使用.Select拡張方法は、学生、グレードおよび教師エンティティを含みます。これは、同じSQLクエリのThenInclude上記()メソッドを実行します。

遅延ロード(遅延ロード)と明示的にロードされる(明示的なロード)についてEFコア3.1は、元の2.0バージョンのサポートは、期限が切れている、あなたは、公式ドキュメントを参照することができます:

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

おすすめ

転載: www.cnblogs.com/AlexanderZhao/p/12289193.html