con la siguiente estructura de la tabla (columnas extraños eliminados)incluir y donde la causa predicado combinación izquierda en lugar de combinación interna
create table [Events]
(
ID int not null identity,
Name nvarchar(128) not null,
constraint PK_Events primary key(ID)
)
create table [Donations]
(
ID int not null identity,
EventID int not null,
Amount decimal(10, 2) not null,
constraint PK_Donations primary key(ID),
constraint FK_Donations_Events foreign key(EventID) references [Events](ID) on update no action on delete no action
)
yo uso las siguientes LINQ a Entidades consultas:
// 1
ents.Donations.Where(d => d.Amount > 25.0m && d.Event.Name.Contains("Run")).ToList();
// 2
ents.Donations.Include("Event").Where(d => d.Amount > 25.0m).ToList();
// 3
ents.Donations.Include("Event").Where(d => d.Amount > 25.0m && d.Event.Name.Contains("Run")).ToList();
Produce (a partir de un Analizador de SQL):
-- 1
SELECT
[Extent1].[ID] AS [ID],
[Extent1].[EventID] AS [EventID],
[Extent1].[Amount] AS [Amount]
FROM [dbo].[Donations] AS [Extent1]
INNER JOIN [dbo].[Events] AS [Extent2] ON [Extent1].[EventID] = [Extent2].[ID]
WHERE ([Extent1].[Amount] > 25.0) AND ([Extent2].[Name] LIKE N'%Run%')
-- 2
SELECT
[Extent1].[ID] AS [ID],
[Extent1].[EventID] AS [EventID],
[Extent1].[Amount] AS [Amount],
[Extent2].[ID] AS [ID1],
[Extent2].[Name] AS [Name]
FROM [dbo].[Donations] AS [Extent1]
INNER JOIN [dbo].[Events] AS [Extent2] ON [Extent1].[EventID] = [Extent2].[ID]
WHERE [Extent1].[Amount] > 25.0
-- 3
SELECT
[Extent1].[ID] AS [ID],
[Extent1].[EventID] AS [EventID],
[Extent1].[Amount] AS [Amount],
[Extent3].[ID] AS [ID1],
[Extent3].[Name] AS [Name]
FROM [dbo].[Donations] AS [Extent1]
INNER JOIN [dbo].[Events] AS [Extent2] ON [Extent1].[EventID] = [Extent2].[ID]
LEFT OUTER JOIN [dbo].[Events] AS [Extent3] ON [Extent1].[EventID] = [Extent3].[ID]
WHERE ([Extent1].[Amount] > 25.0) AND ([Extent2].[Name] LIKE N'%Run%')
¿por qué en la consulta tercero, ¿genera una LEFT OUTER JOIN
en la tabla Events
por segunda vez? Si bien la consulta produce resultados correctos, parece extraño, ¿por qué EF/LINQ no puede reutilizar [Extent2]
en la cláusula SELECT
y WHERE
, y por qué es LEFT OUTER JOIN
?
Estoy usando Visual Studio 2010 sp1 .NET 4 y me estoy conectando a Sql Server 2008 Express.
La segunda consulta usa 'Include' pero no produce una combinación left. – Matthew
Muy buena pregunta, no me di cuenta. Esto parece estar de vuelta para mí. La segunda consulta debe tener una combinación a la izquierda para que Include no cause efectos secundarios y la tercera consulta debería tener una combinación interna, ya que necesita una fila de evento de todos modos. – MikeKulls
Una combinación a la izquierda tendría sentido si fuera una columna con posibilidad de nulos, o si no tuviera integridad referencial en ella. – Matthew