Pergunta

Eu estou preso em traduzir uma junção externa esquerda de LINQToSQL que retorna linhas pai únicas.

Eu tenho 2 tabelas (Projeto, Project_Notes, e é um relacionamento 1-muitos ligado por project_id). Estou fazendo uma pesquisa palavra-chave em várias colunas na mesa de 2 e eu só quero retornar os projectos únicos se uma coluna no Project_Notes contém uma palavra-chave. Eu tenho essa sequência LinqToSQL indo mas parece estar voltando várias linhas de projeto. Talvez fazer um Exist de alguma forma em LINQ? Ou talvez um groupby de algum tipo?

Aqui está o LINQToSQL:

 query = from p in query
 join n in notes on p.PROJECT_ID equals n.PROJECT_ID into projectnotes
 from n in notes.DefaultIfEmpty()
 where n.NOTES.Contains(cwForm.search1Form)
 select p;

aqui está o SQL-lo produzido a partir de profiler

exec sp_executesql N'SELECT [t2]. [Título], [t2]. [Estado], [t2]. [PROJECT_ID], [T2]. [PROVIDER_ID], [t2]. [CATEGORY_ID], [t2]. [City], [t2]. [UploadedDate], [T2]. [SubmittedDate], [t2]. [Project_Type] DA (SELECCIONAR ROW_NUMBER () SOBRE O (POR ORDEM [T0]. [UploadedDate]) AS [ROW_NUMBER], [t0]. [Título], [t0]. [Estado], [t0]. [PROJECT_ID], [T0]. [PROVIDER_ID], [t0]. [CATEGORY_ID], [t0]. [City], [t0]. [UploadedDate], [T0]. [SubmittedDate], [t0]. [Project_Type] a partir de [DBO]. [Projectos] AS [t0] LEFT OUTER JOIN [Dbo]. [PROJECT_NOTES] AS [t1] NO 1 = 1 ONDE ([t1]. [Notas] como @ p0) E ([T0] .SubmittedDate]> = @ p1) e ([t0]. [SubmittedDate] <@ p2) E ([t0]. [PROVIDER_ID] = @ P3) E ([t0]. [CATEGORY_ID] IS NULL)) AS [t2] Onde [t2]. [ROW_NUMBER] ENTRE @ P4 + 1 E @ + @ p4 p5 POR ORDEM [t2]. [ROW_NUMBER] 'N' @ p 0 VARCHAR (9), @ p1 de data e hora, data e hora @ P2, P3 @ int, @ p4 int, @ p5 int', @ p0 = '% chicago%', @ p1 = '' 2000/09/02 00: 00: 00: 000 '', @ p2 = '' 2009-03-02 00: 00: 00: 000 '', @ p3 = 1000, @ p4 = 373620, @ p5 = 20

Esta consulta retorna todos os mutiples do 1-muitos nos resultados. Eu encontrei como fazer um Exists em LINQ a partir daqui. http: / /www.linq-to-sql.com/linq-to-sql/t-sql-to-linq-upgrade/linq-exists/

Aqui está a LINQToSQL usando Exists:

query = from p in query
where (from n in notes
where n.NOTES.Contains(cwForm.search1Form)
select n.PROJECT_ID).Contains(p.PROJECT_ID)
select p;

A instrução SQL gerado:

exec sp_executesql N'SELECT COUNT (*) AS [valor] de [dbo]. [Projetos] AS [t0] ONDE (EXISTE (SELECCIONAR NULL AS [vazio] DE [dbo]. [PROJECT_NOTES] AS [t1] ONDE ([T1] .PROJECT_ID] = ([t0]. [PROJECT_ID])) E ([t1]. [Notas] como @ p0))) E ([T0]. [SubmittedDate]> = @ p1) e ([t0]. [SubmittedDate] <@ p2) E ([t0]. [PROVIDER_ID] = @ P3) E ([t0]. [CATEGORY_ID] IS NULL) 'N' @ p 0 VARCHAR (9), @ p1 de data e hora, data e hora @ P2, P3 @ int', @ p0 = '% chicago%', @ p1 = '' 2000/09/02 00: 00: 00: 000 '', @ p2 = '' 2009-03-02 00: 00: 00: 000 '', @ p3 = 1000

Eu fico um tempo limite SQL do databind() de usar Exists.

Foi útil?

Solução

parece estar voltando várias linhas de projeto

Sim, é assim que se juntar obras. Se um projeto tem 5 notas correspondentes, ele mostrar-se 5 vezes.


E se o problema é - "Join" é o idioma errado

Você deseja filtrar os projectos para aqueles cujas notas contêm determinado texto:

var query = db.Project
  .Where(p => p.Notes.Any(n => n.NoteField.Contains(searchString)));

Outras dicas

Você vai ter que usar o método de extensão DefaultIfEmpty. Há algumas perguntas sobre SO já que mostram como fazer isso. Aqui está um bom exemplo:

Como posso realizar um aninhado, Adicionar e Grupo em LINQ?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top