当我包含两次相同的字段时会发生什么,这意味着我从db获取实体并使用EF .include
选项。我的意思是这样的:
我有:
.Include(x => x.Student)
.Include(x => x.Car)
.Include(x => x.Student)
这是模型:
Person has a Student
Person has a car
所以两次(因为我的人只有学生)包括(错误地)学生,是否有问题?
附:我只希望它包含在内!因为我只有一个学生。
ef会抱怨这个吗?我尝试了它似乎没问题,但我不知道这个含义。任何人都可以解释/详述吗?搜索了一下,但无法确定任何问题。
答案 0 :(得分:4)
拿这个样本:
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]
让我们创建一个复制包含的查询:
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也足够智能生成相同的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();
重复包含和多次。这是生成的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]
再次使用相同的代码。所以,是的。我们可以说它会好的,虽然有点奇怪的事情要做。
希望这有帮助!
答案 1 :(得分:2)
如果您调用两次,则会生成相同的查询。结果相同,就像这样
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]
答案 2 :(得分:1)
这完全有效,无论如何都不会绊倒EF。考虑如何包含挂起像Student
之类的引用的其他引用和集合。你可以像这样写它们。您提出的建议不会比以下示例更加混淆EF。
.Include(x => x.Student.Teacher)
.Include(x => x.Car)
.Include(x => x.Student.DrivingLog)
答案 3 :(得分:1)
对于EF 6
使用System.Data.Entity;
query.Include(x => x.Collection.Select(y => y.Property))
确保使用System.Data.Entity添加;以获得包含lambda的Include版本。
对于EF Core
使用新方法ThenInclude
query.Include(x => x.Collection)
.ThenInclude(x => x.Property);