如何对EF中的多个条目进行显式加载

本文关键字:加载 EF | 更新日期: 2023-09-27 18:19:45

我在web上看到了一些显式加载示例,如下所示:

参考:http://www.entityframeworktutorial.net/EntityFramework4.3/explicit-loading-with-dbcontext.aspx

using (var context = new SchoolDBEntities())
    {
        context.Configuration.LazyLoadingEnabled = false;
        var student = (from s in context.Students
                            where s.StudentName == "Bill"
                            select s).FirstOrDefault<Student>();
        context.Entry(student).Collection(s => s.Courses).Load();
    }

或参考:http://codingcanvas.com/loading-nested-entities-in-entityframework/

using (var context = new EmployeeContext())
            {
                var employee = context.Employees.FirstOrDefault();
                context.Entry(employee).Reference(x => x.ContactDetails).Load();
                context.Entry(employee).Reference(x => x.EmpDepartment).Load();
                context.Entry(employee.EmpDepartment).Collection(x => x.DepartmentProjects).Load();
            };

//SQL生成---------------------------------------------

SELECT TOP (1) 1.[EmployeeNo]          AS [EmployeeNo],
               1.[FirstName]           AS [FirstName],
               1.[LastName]            AS [LastName],
               1.[Age]                 AS [Age],
               1.[DepartmentId]        AS [DepartmentId],
               1.[FunctionId]          AS [FunctionId],
               1.[TypeOfEmployee]      AS [TypeOfEmployee],
               1.[Project_ProjectCode] AS [Project_ProjectCode]
FROM   [dbo].[Employees] AS 1
SELECT [Extent1].[EmployeeNo]   AS [EmployeeNo],
       [Extent1].[Address]      AS [Address],
       [Extent1].[Phone]        AS [Phone],
       [Extent1].[Fax]          AS [Fax],
       [Extent1].[Mobile]       AS [Mobile],
       [Extent1].[LocationCord] AS [LocationCord]
FROM   [dbo].[EmployeeContacts] AS [Extent1]
WHERE  [Extent1].[EmployeeNo] = 1 /* @EntityKeyValue1 */
SELECT [Extent1].[DepartmentId]   AS [DepartmentId],
       [Extent1].[DepartmentCode] AS [DepartmentCode],
       [Extent1].[DepartmentName] AS [DepartmentName]
FROM   [dbo].[Departments] AS [Extent1]
WHERE  [Extent1].[DepartmentId] = 11 /* @EntityKeyValue1 */
SELECT [Extent1].[ProjectCode]             AS [ProjectCode],
       [Extent1].[ProjectName]             AS [ProjectName],
       [Extent1].[ProjectDescription]      AS [ProjectDescription],
       [Extent1].[Department_DepartmentId] AS [Department_DepartmentId]
FROM   [dbo].[Projects] AS [Extent1]
WHERE  ([Extent1].[Department_DepartmentId] IS NOT NULL)
       AND ([Extent1].[Department_DepartmentId] = 11 /* @EntityKeyValue1 */)

这很好,但如果我删除FirstOrDefault()并放入Where(x=> x.Age > 20),它会返回一个集合,而不仅仅是TOP(1)。我不能再使用context.Entry(employee)了,对吧?因为它仅适用于单个条目对象。

现在,我如何做与示例相同的操作,但我们使用Where来选择多个条目并加载它们的引用,而不是单个条目?

如何对EF中的多个条目进行显式加载

Entry方法使您能够控制附加到当前上下文的实体,因此在使用它之前,必须附加该实体。

实现目标的唯一方法是在所有检索到的实体上循环,并加载引用的数据。

using (var context = new EmployeeContext())
        {
            var employee = context.Employees.Where(x=> x.Age > 20);
            foreach( var item in employee)
            {
                context.Entry(item).Reference(x => x.ContactDetails).Load();
                context.Entry(item).Reference(x => x.EmpDepartment).Load();
                context.Entry(item.EmpDepartment).Collection(x => x.DepartmentProjects).Load();
            }
        };

显然,这在很大程度上取决于您面临的记录数量,IMHO,如果您的外键和索引得到了优化,Include(然后是JOIN数据库端)是最佳选择,因为所有数据都是通过单个数据库调用检索的,但在某些情况下,更不同的单个SELECT可能是一个有效的选项。