2013-04-15 27 views
44

Quale sarebbe la query per:Entity Framework Query per inner join

select s.* from Service s 
inner join ServiceAssignment sa on sa.ServiceId = s.Id 
where sa.LocationId = 1 

in Entity Framework?

Questo è quello che ho scritto:

var serv = (from s in db.Services 
       join sl in Location on s.id equals sl.id 
       where sl.id = s.id 
       select s).ToList(); 

ma è sbagliato. Qualcuno può guidarmi sul sentiero?

+0

guardare lì: http : //stackoverflow.com/questions/37324/what-is-the-syntax-for-an-inner-join-in-linq-to-sql –

+1

Stai utilizzando l'assegnazione '=' anziché il confronto '==' in clausola 'where'. Inoltre non ti serve se sei già iscritto su quei campi. –

+2

Non è 'dove sl.id = s.id' è ridondante con la condizione di join? –

risposta

71
from s in db.Services 
join sa in db.ServiceAssignments on s.Id equals sa.ServiceId 
where sa.LocationId == 1 
select s 

Dove db è il vostro DbContext. La query generata sarà simile (esempio per EF6):

SELECT [Extent1].[Id] AS [Id] 
     -- other fields from Services table 
FROM [dbo].[Services] AS [Extent1] 
INNER JOIN [dbo].[ServiceAssignments] AS [Extent2] 
    ON [Extent1].[Id] = [Extent2].[ServiceId] 
WHERE [Extent2].[LocationId] = 1 
+2

Non è un join esterno sinistro? –

+3

@JonathanWood No, questo è inner join. Il join esterno sinistro verrà generato dal join di gruppo. –

+0

Potremmo usare da s in db.Services join sa in db.ServiceAssignments su s.Id equivale a sa.ServiceId ** || s.Id è uguale a null ** dove sa.LocationId == 1 select s –

4

È possibile utilizzare una proprietà di navigazione se disponibile. Produce un inner join in SQL.

from s in db.Services 
where s.ServiceAssignment.LocationId == 1 
select s 
34

Nel caso qualcuno è interessato alla sintassi del metodo, se si dispone di una proprietà di navigazione, è modo semplice:

db.Services.Where(s=>s.ServiceAssignment.LocationId == 1); 

Se non lo fai, a meno che non ci sia qualche Join() esclusione Sono a conoscenza di , penso che sembra piuttosto nodosi (e io sono una sintassi puristi Method):

db.Services.Join(db.ServiceAssignments, 
    s => s.Id, 
    sa => sa.ServiceId, 
    (s, sa) => new {service = s, asgnmt = sa}) 
.Where(ssa => ssa.asgnmt.LocationId == 1) 
.Select(ssa => ssa.service); 
+0

Questo non funzionerebbe se l'FK su ServiceAssignment dovesse essere annullabile , lo farebbe? – Cardin

+3

@Cardin in tal caso vorrei suggerire il C# 6?. operatore. Se non lo hai, controlla la presenza di null prima di utilizzare la proprietà di navigazione. Generalmente, non si aggiunge un gruppo di codice difensivo negli esempi, in modo da non confondere il punto principale. Se l'FK è annullabile, appare come segue: (C# 6) 'db.Services.Where (s => s? .ServiceAssignment.LocationId == 1);' o simile in C# 5: 'db.Services.Where (s => s.ServiceAssignment! = null && s.ServiceAssignment.LocationId == 1);' –

+0

@ MichaelBlackburn È vero! È più comprensibile. Grazie per il chiarimento. :) – Cardin