Pergunta
Eu tenho 2 tabelas em SQL.
Table 1
Step Id
Step Name
Table 2
Profile Id
Step Id
Completed
Eu gostaria de retornar os seguintes resultados, mesmo se não houver correspondência na tabela 2:
Results
Table1.Step Id
Table1.Step Name
Table2.Profile Id
Table2.Completed
A maneira que eu estou fazendo isso em SQL é a seguinte:
select * from [Table 1] t1
left join [Table 2] t2
on t1.Step Id = t2.Step Id
Isso produz os resultados que eu esperava.
Quando eu traduzir isso em LINQ:
public static List<UserCompletion> GetStepCompletion(string category, string profileid) {
List<Step> step = GetSteps(category);
List<UserStep> userStep = GetUserSteps(category, profileId);
var q = from s in step
join us in userStep
on s.Id equals us.StepId
select new UserCompletion
{
StepId = s.Id,
Headline = s.StepName,
ProfileId = us.ProfileId
Completed= us.Completed
};
return q.ToList();
}
Ele funciona, mas como um não juntar uma junção esquerda. Eu só fico combinando resultados de volta.
Além disso, UserCompletion é um objeto que eu voltar a partir deste método.
Eu tenho sido batendo minha cabeça sobre isso por alguns dias ... qualquer ajuda seria apreciada.
Solução
Você também pode tentar isso (assumindo us.Completed é boolean):
var q = from s in step
let us = (from i in userStep where s.Id = i.StepId).SingleOrDefault()
select new UserCompletion
{
StepId = s.Id,
Headline = s.StepName,
ProfileId = us.ProfileId
Completed = us == null ? false : us.Completed
};
Isto não vai se transformar em uma junção em SQL, mas um SELECT aninhada declaração algo como isto:
select
StepId, Headline, ProfileId,
isnull((select top(1) Completed from userStep where StepId = Id), 0) as Completed
from step
Outras dicas
Tente algo ao longo das linhas do seguinte:
var q = from s in step
join us in userStep
on s.Id equals us.StepId into tmpjoin
from x in tmpjoin.DefaultIfEmpty()
select new UserCompletion { ... }
Encontrado-lo.
Parece que eu preciso adicionar uma avaliação sobre o item que "pode" ser nula.
Eu adicionei o seguinte ao meu select
Completed = (x == null) ? String.Empty : x.Completed