Behaviour when including the same field twice in entity framework linq
Take this sample:
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; }
}
A rent contains the Student and the Car.
Lets make a query with unique Include clauses:
var rents = ctx.Rents
.Include(x => x.Student)
.Include(x => x.Car)
//.Include(x => x.Student)
.ToList();
This is the generated 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]
Let's make a query duplicating an Include:
var rents = ctx.Rents
.Include(x => x.Student)
.Include(x => x.Car)
.Include(x => x.Student)
.ToList();
You'll get this 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]
As you can see, EF is smart enough to generate the same sql even when you specify an Include more than once.
UPDATE: Repeated includes (many times)
Let's try this:
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 Includes and several times. And here's the generated 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]
Just the same code again. So, yes. We could say it'll be ok, although a little weird thing to do.
Hope this helps!
If you call it twice, the same query will be generated. Result the same, something like this
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]