Pregunta

Estoy atascado en traducir una combinación externa izquierda de LINQToSQL que devuelve filas primarias únicas.

Tengo 2 tablas (Project, Project_Notes, y es una relación de 1-muchos vinculada por Project_ID). Estoy haciendo una búsqueda de palabras clave en varias columnas en la tabla 2 y solo quiero devolver los proyectos únicos si una columna en Project_Notes contiene una palabra clave. Tengo esta secuencia linqtoSQl funcionando pero parece que devuelve varias filas del Proyecto. ¿Quizás hacer un Exist de alguna manera en LINQ? ¿O tal vez un grupo de algún tipo?

Aquí está el 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;

aquí está el SQL que produjo del generador de perfiles

  

exec sp_executesql N'SELECT [t2]. [Título], [t2]. [Estado], [t2]. [PROYECTO_ID],   [t2]. [PROVIDER_ID], [t2]. [CATEGORY_ID], [t2]. [Ciudad], [t2]. [UploadedDate],   [t2]. [EnviadoDate], [t2]. [Project_Type] FROM (SELECT ROW_NUMBER () OVER (ORDER BY   [t0]. [UploadedDate]) AS [ROW_NUMBER], [t0]. [Title], [t0]. [State], [t0]. [PROJECT_ID],   [t0]. [PROVIDER_ID], [t0]. [CATEGORY_ID], [t0]. [Ciudad], [t0]. [UploadedDate],   [t0]. [SubmitDate], [t0]. [Project_Type] FROM [dbo]. [PROJECTS] AS [t0] IZQUIERDA EXTERIOR UNIRSE   [dbo]. [PROYECTO_NOTAS] COMO [t1] EN 1 = 1 DONDE ([t1]. [NOTAS] ME GUSTA @ p0) Y   ([t0] .SubmittedDate] > = @ p1) AND ([t0]. [SubmitDate] < @ p2) AND ([t0]. [PROVIDER_ID] =   @ p3) Y ([t0]. [CATEGORY_ID] ES NULO)) COMO [t2] DONDE [t2]. [ROW_NUMBER] ENTRE @ p4 + 1   Y @ p4 + @ p5 ORDER BY [t2]. [ROW_NUMBER] ', N' @ p0 varchar (9), @ p1 datetime, @ p2 datetime, @ 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 devuelve todos los mutiples de la relación 1-muchos en los resultados. Encontré cómo hacer un Exists en LINQ desde aquí. http: / /www.linq-to-sql.com/linq-to-sql/t-sql-to-linq-upgrade/linq-exists/

Aquí está el LINQToSQL usando databind():

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;

La instrucción SQL generada:

  

exec sp_executesql N'SELECT COUNT (*) AS [value] FROM [dbo]. [PROJECTS] AS [t0] WHERE   (EXISTE (SELECCIONE NULL COMO [VACÍO] DE [dbo]. [PROYECTO_NOTAS] COMO [t1] DONDE   ([t1] .PROJECT_ID] = ([t0]. [PROJECT_ID])) AND ([t1]. [NOTES] LIKE @ p0))) AND   ([t0]. [EnviadoDate] > = @ p1) AND ([t0]. [EnviadoDate] < @ p2) AND ([t0]. [PROVIDER_ID] =   @ p3) AND ([t0]. [CATEGORY_ID] IS NULL) ', N' @ p0 varchar (9), @ p1 datetime, @ p2 datetime, @ p3   int ', @ p0 ='% chicago% ', @ p1 =' '2000-09-02 00: 00: 00: 000' ', @ p2 =' '2009-03-02   00: 00: 00: 000 '', @ p3 = 1000

Obtuve un tiempo de espera de SQL de <=> al usar <=>.

¿Fue útil?

Solución

  

parece estar devolviendo múltiples filas del Proyecto

Sí, así es como funciona join. Si un proyecto tiene 5 notas coincidentes, se mostrará 5 veces.


¿Qué pasa si el problema es - " Únete " es el idioma equivocado!

Desea filtrar los proyectos a aquellos cuyas notas contienen cierto texto:

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

Otros consejos

Tendrá que usar el método de extensión DefaultIfEmpty. Ya hay algunas preguntas sobre SO que muestran cómo hacer esto. Aquí hay un buen ejemplo:

¿Cómo puedo realizar un Unir, Agregar y Agrupar anidados en LINQ?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top