Question

Je suis coincé dans la traduction d'une jointure externe gauche à partir de LINQToSQL qui renvoie des lignes parent uniques.

J'ai 2 tables (Project, Project_Notes, et c'est une relation à plusieurs liée par Project_ID). Je fais une recherche par mot-clé sur plusieurs colonnes de la table et je veux seulement renvoyer les projets uniques si une colonne dans Project_Notes contient un mot-clé. J'ai cette séquence linqtoSQl en cours, mais elle semble renvoyer plusieurs lignes de projet. Peut-être faire un Exist en quelque sorte dans LINQ? Ou peut-être un groupe de quelque sorte?

Voici le 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;

voici le code SQL produit par le profileur

  

exec sp_executesql N'SELECT [t2]. [Titre], [t2]. [Etat], [t2]. [PROJECT_ID],   [t2]. [PROVIDER_ID], [t2]. [CATEGORY_ID], [t2]. [Ville], [t2]. [UploadedDate],   [t2]. [SubmittedDate], [t2]. [Type de projet] FROM (SELECT ROW_NUMBER () OVER (ORDER BY   [t0]. [UploadedDate]) COMME [ROW_NUMBER], [t0]. [Titre], [t0]. [État], [t0]. [IDENTIFICAMENT],   [t0]. [PROVIDER_ID], [t0]. [CATEGORY_ID], [t0]. [Ville], [t0]. [Date uploadée],   [t0]. [SubmittedDate], [t0]. [Type de projet] DE [dbo]. [PROJECTS] COMME [t0] LEFT OUTER JOIN   [dbo]. [PROJECT_NOTES] COMME [t1] ON 1 = 1 O ([t1]. [NOTES] LIKE @ p0) ET   ([t0] .SubmittedDate] > = @ p1) ET ([t0]. [SubmittedDate] < @ p2) ET ([t0]. [PROVIDER_ID] =   @ p3) ET ([t0]. [CATEGORY_ID] EST NULL)) COMME [t2] O [t2]. [ROW_NUMBER] ENTRE @ @ p4 + 1   AND @ 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

Cette requête retourne tous les multiples de la relation 1-plusieurs dans les résultats. J'ai trouvé comment faire un Exists dans LINQ à partir d'ici. http: / /www.linq-to-sql.com/linq-to-sql/t-sql-to-linq-upgrade/linq-exists/

Voici le LINQToSQL utilisant 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;

L'instruction SQL générée:

  

exec sp_executesql N'SELECT COUNT (*) AS [valeur] FROM [dbo]. [PROJECTS] AS [t0] WHERE   (EXISTS (SÉLECTIONNER NULL COMME [VIDE]] À PARTIR DE [dbo]. [PROJECT_NOTES] COMME [t1] WHERE   ([t1] .PROJECT_ID] = ([t0]. [ID PROJECT])) ET ([t1]. [NOTES] LIKE @ p0))) ET   ([t0]. [SubmittedDate] > = @ p1) AND ([t0]. [SubmittedDate] < @ 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

Je reçois un délai d'attente SQL du <=> utilisation de <=>.

Était-ce utile?

La solution

  

il semble renvoyer plusieurs lignes de projet

Oui, c'est comme ça que les jointures fonctionnent. Si un projet a 5 notes correspondantes, il apparaît 5 fois.

Et si le problème est - & "Rejoindre &"; est le mauvais langage!

Vous souhaitez filtrer les projets en fonction de ceux dont les notes contiennent un certain texte:

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

Autres conseils

Vous allez devoir utiliser la méthode d'extension DefaultIfEmpty. Il y a déjà quelques questions sur SO qui montrent comment faire cela. Voici un bon exemple:

Comment puis-je effectuer une Adhésion, ajout et groupe imbriqués dans LINQ?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top