在实体框架linq中两次包含相同字段时的行为
本文关键字:字段 包含相 两次 linq 框架 实体 | 更新日期: 2023-09-27 18:14:58
当我包含相同的字段两次时会发生什么,这意味着我从数据库中获取一个实体,我使用EF .include
选项。我的意思是:
我有:
.Include(x => x.Student)
.Include(x => x.Car)
.Include(x => x.Student)
这是模型:
Person has a Student
Person has a car
所以通过(错误地)包含学生两次(因为我的人只有一个学生),有问题吗?
附言:我只希望它包含一次!因为我只有一个学生。他对此有抱怨吗?我试了一下,似乎还行,但我不知道这意味着什么。有人能解释一下吗?搜索了一下,但没有发现任何问题。
举个例子:
public class RentContext : DbContext
{
public DbSet<Student> Students { get; set; }
public DbSet<Rent> Rents { get; set; }
public DbSet<Car> Cars { get; set; }
}
public class Car
{
public int Id { get; set; }
public string Model { get; set; }
public double Price { get; set; }
}
public class Rent
{
public int Id { get; set; }
public Student Student { get; set; }
public Car Car { get; set; }
}
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
public int Year { get; set; }
}
租金包含学生和汽车。
让我们用唯一的Include子句创建一个查询:
var rents = ctx.Rents
.Include(x => x.Student)
.Include(x => x.Car)
//.Include(x => x.Student)
.ToList();
生成的sql:
SELECT
[Extent1].[Id] AS [Id],
[Extent2].[Id] AS [Id1],
[Extent2].[Name] AS [Name],
[Extent2].[Year] AS [Year],
[Extent3].[Id] AS [Id2],
[Extent3].[Model] AS [Model],
[Extent3].[Price] AS [Price]
FROM [dbo].[Rents] AS [Extent1]
LEFT OUTER JOIN [dbo].[Students] AS [Extent2] ON [Extent1].[Student_Id] = [Extent2].[Id]
LEFT OUTER JOIN [dbo].[Cars] AS [Extent3] ON [Extent1].[Car_Id] = [Extent3].[Id]
让我们创建一个复制Include的查询:
var rents = ctx.Rents
.Include(x => x.Student)
.Include(x => x.Car)
.Include(x => x.Student)
.ToList();
你会得到这样的sql:
SELECT
[Extent1].[Id] AS [Id],
[Extent2].[Id] AS [Id1],
[Extent2].[Name] AS [Name],
[Extent2].[Year] AS [Year],
[Extent3].[Id] AS [Id2],
[Extent3].[Model] AS [Model],
[Extent3].[Price] AS [Price]
FROM [dbo].[Rents] AS [Extent1]
LEFT OUTER JOIN [dbo].[Students] AS [Extent2] ON [Extent1].[Student_Id] = [Extent2].[Id]
LEFT OUTER JOIN [dbo].[Cars] AS [Extent3] ON [Extent1].[Car_Id] = [Extent3].[Id]
正如您所看到的,EF足够聪明,即使您多次指定Include也能生成相同的sql。
更新:重复包含(多次)
让我们试试这个:
var rents = ctx.Rents
.Include(x => x.Student)
.Include(x => x.Car)
.Include(x => x.Car)
.Include(x => x.Car)
.Include(x => x.Car)
.Include(x => x.Car)
.Include(x => x.Car)
.Include(x => x.Car)
.Include(x => x.Car)
.Include(x => x.Car)
.Include(x => x.Car)
.Include(x => x.Car)
.Include(x => x.Car)
.Include(x => x.Car)
.Include(x => x.Car)
.Include(x => x.Car)
.Include(x => x.Car)
.Include(x => x.Car)
.Include(x => x.Car)
.Include(x => x.Car)
.Include(x => x.Car)
.Include(x => x.Car)
.Include(x => x.Car)
.Include(x => x.Car)
.Include(x => x.Car)
.Include(x => x.Student)
.Include(x => x.Student)
.Include(x => x.Student)
.Include(x => x.Student)
.Include(x => x.Student)
.Include(x => x.Student)
.Include(x => x.Student)
.Include(x => x.Student)
.Include(x => x.Student)
.Include(x => x.Student)
.Include(x => x.Student)
.Include(x => x.Student)
.Include(x => x.Student)
.ToList();
Repeated包括和多次。下面是生成的sql:
SELECT
[Extent1].[Id] AS [Id],
[Extent2].[Id] AS [Id1],
[Extent2].[Name] AS [Name],
[Extent2].[Year] AS [Year],
[Extent3].[Id] AS [Id2],
[Extent3].[Model] AS [Model],
[Extent3].[Price] AS [Price]
FROM [dbo].[Rents] AS [Extent1]
LEFT OUTER JOIN [dbo].[Students] AS [Extent2] ON [Extent1].[Student_Id] = [Extent2].[Id]
LEFT OUTER JOIN [dbo].[Cars] AS [Extent3] ON [Extent1].[Car_Id] = [Extent3].[Id]
还是同样的代码。所以,是的。我们可以说它会没事的,尽管这样做有点奇怪。
希望这对你有帮助!
如果调用两次,将生成相同的查询。结果相同,像这样
SELECT
[Extent1].[Id] AS [Id],
[Extent1].[Title] AS [Title],
[Extent1].[PersonId] AS [PersonId],
[Extent2].[Id] AS [Id1],
[Extent2].[Name] AS [Name]
FROM [dbo].[Books] AS [Extent1]
INNER JOIN [dbo].[People] AS [Extent2] ON [Extent1].[PersonId] = [Extent2].[Id]
这是完全有效的,无论如何都不会使EF出错。考虑如何包含挂起引用(如Student
)的附加引用和集合。你可以这样写。你的建议不会比下面的例子更让EF感到困惑。
.Include(x => x.Student.Teacher)
.Include(x => x.Car)
.Include(x => x.Student.DrivingLog)