2014-12-07 2 views
1

Я пытаюсь преобразовать SQL query в Linq, содержащий несколько левых внешних объединений, но я встречаю странную ситуацию.SQL-запрос Linq с несколькими левыми внешними соединениями

Соответствующая часть моего SQL является:

SELECT * FROM dbo.SessionDetails as sd 
    left outer join dbo.VoipDetails as vd on vd.SessionIdTime = sd.SessionIdTime and vd.SessionIdSeq = sd.SessionIdSeq 
    left outer join dbo.Gateways as fgw on vd.FromGatewayId = fgw.GatewayId 

Мой Linq запрос до сих пор:

var query = from sd in dbo.SessionDetails 
    join vd in dbo.VoipDetails on new { sd.SessionIdTime, sd.SessionIdSeq } equals new { vd.SessionIdTime, vd.SessionIdSeq } into sdvd 
    from v in sdvd.DefaultIfEmpty() 
     join fgw in dbo.Gateways on vd.FromGatewayId equals fgw.GatewayId into sdgw 
     from g in sdvd.DefaultIfEmpty() 
      select sd; 

Я получаю знак ошибки на vd.FromGatewayId говорил мне, что The name 'vd' is not in scope on the left side of 'equals'. Consider swapping the expressions on either side of 'equals'.
Однако, если я обмениваю стороны с gw.GatewayId, тогда я получаю такое же сообщение об ошибке как для vd, так и для gw. Может кто-нибудь предложить правильный синтаксис здесь? Пожалуйста, имейте в виду, что у меня есть еще несколько левых соединений, которые нужно добавить после того, как я получу базовый синтаксис.

ответ

2

Я считаю, что проблема заключается в том, что вы пытаетесь получить доступ к значению, которое не имеет области в запросе. Я считаю, что причиной этого является то, что вы указываете корабль отношения и затем присваиваете эти значения коллекции, которая называется sdvd, в этот момент вы не можете попасть в vd. Тем не менее, вы тогда делаете from v in sdvd.DefaultIfEmpty(), делая так, что у вас есть доступ к строкам в sdvd, которые являются теми же значениями, которые находятся в том, что вы думаете, vd. Вы должны иметь возможность использовать v вместо vd. Мне пришлось издеваться над чем-то, чтобы проверить, поэтому я не смог проверить именно этот запрос, но следующее должно выполняться.

var query = from sd in dbo.SessionDetails 
    join vd in dbo.VoipDetails on new { sd.SessionIdTime, sd.SessionIdSeq } equals new { vd.SessionIdTime, vd.SessionIdSeq } into sdvd 
    from v in sdvd.DefaultIfEmpty() 
     join fgw in dbo.Gateways on v.FromGatewayId equals fgw.GatewayId into sdgw 
     from g in sdvd.DefaultIfEmpty() 
      select sd; 

EDIT 2014/12/08

Для того, чтобы увидеть, как оператор LINQ переводит к SQL, я хотел бы предложить вам установить https://www.linqpad.net/. Вы можете настроить соединение и проверить свои запросы там и посмотреть sql в представлении результатов.

Поскольку у меня нет структуры данных для вопроса, это будет сложно. Тем не менее я издевался что-то:

from sd in Employees 
    join vd in TimeEntries on new { sd.EmployeeID } equals new { vd.EmployeeID } into sdvd 
    from v in sdvd.DefaultIfEmpty() 
     join fgw in EmployeeGroupDetails on v.EmployeeID equals fgw.EmployeeID into sdgw 
     from g in sdgw.DefaultIfEmpty() 
      select sd 

Это дает:

SELECT [t0].* 
FROM [Employee] AS [t0] 
LEFT OUTER JOIN [TimeEntry] AS [t1] ON [t0].[EmployeeID] = [t1].[EmployeeID] 
LEFT OUTER JOIN [EmployeeGroupDetail] AS [t2] ON [t1].[EmployeeID] = [t2].[EmployeeID] 

Он пришел обратно с правом соединения.

+0

Я мог бы быть недопониманием, но для продолжения создания left-external-join, не должно быть 'on v.FromGatewayId равно fgw.GatewayId в sdgw из g в sdgw.DefaultIfEmpty()', а не ' sdvd.DefaultIfEmpty() 'снова? – Black

Смежные вопросы