在实体框架linq中包含两次相同字段时的行为

fir*_*ast 5 c# linq entity-framework

当我将相同的字段包含两次时会发生什么,这意味着我从db获取一个实体并使用EF .include选项.我的意思是:
我有:

.Include(x => x.Student)
.Include(x => x.Car)
.Include(x => x.Student)
Run Code Online (Sandbox Code Playgroud)

这是模型:

Person has a Student
Person has a car
Run Code Online (Sandbox Code Playgroud)

因此,通过包括(错误地)学生两次(因为我的人只有一个学生),是否存在问题?
PS我只希望它包括ONCE!因为我只有一个学生.ef会抱怨这个吗?我尝试了它似乎没问题,但我不知道这个含义.任何人都可以解释/详述吗?搜索了一下,但无法确定任何问题.

Kar*_*ayo 5

拿这个样本:

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; }
}
Run Code Online (Sandbox Code Playgroud)

租金包含学生和汽车。

让我们使用独特的 Include 子句进行查询:

var rents = ctx.Rents
    .Include(x => x.Student)
    .Include(x => x.Car)
    //.Include(x => x.Student)
    .ToList();
Run Code Online (Sandbox Code Playgroud)

这是生成的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]
Run Code Online (Sandbox Code Playgroud)

让我们做一个复制 Include 的查询:

var rents = ctx.Rents
    .Include(x => x.Student)
    .Include(x => x.Car)
    .Include(x => x.Student)
    .ToList();
Run Code Online (Sandbox Code Playgroud)

你会得到这个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]
Run Code Online (Sandbox Code Playgroud)

如您所见,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();
Run Code Online (Sandbox Code Playgroud)

重复包含和多次。这是生成的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]
Run Code Online (Sandbox Code Playgroud)

只是再次相同的代码。所以,是的。我们可以说一切都会好起来的,尽管这样做有点奇怪。

希望这可以帮助!