Оставлено внешнее соединение и существует в Linq To SQL C # .NET 3.5 - PullRequest
1 голос
/ 02 марта 2009

Я застрял при переводе левого внешнего соединения из LINQToSQL, который возвращает уникальные родительские строки.

У меня есть 2 таблицы (Project, Project_Notes, и это отношение 1-многие, связанные Project_ID). Я выполняю поиск по ключевым словам в нескольких столбцах таблицы 2, и я хочу вернуть уникальные проекты, только если столбец в Project_Notes содержит ключевое слово. У меня есть эта последовательность linqtoSQl собирается, но, похоже, возвращает несколько строк проекта. Может сделать Exist как-нибудь в LINQ? Или, может быть, какой-то групповой?

Вот 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;

вот SQL, полученный от профилировщика

exec sp_executesql N'SELECT [t2]. [Title], [t2]. [State], [t2]. [PROJECT_ID], [t2]. [PROVIDER_ID], [t2]. [CATEGORY_ID], [t2]. [Город], [t2]. [UploadedDate], [t2]. [SubmittedDate], [t2]. [Project_Type] FROM (ВЫБРАТЬ ROW_NUMBER () OVER (ORDER BY [t0]. [UploadedDate]) AS [ROW_NUMBER], [t0]. [Title], [t0]. [State], [t0]. [PROJECT_ID], [t0]. [PROVIDER_ID], [t0]. [CATEGORY_ID], [t0]. [Город], [t0]. [UploadedDate], [t0]. [SubmittedDate], [t0]. [Project_Type] FROM [dbo]. [PROJECTS] AS [t0] ВЛЕВО НАРУЖНОЕ СОЕДИНЕНИЕ [dbo]. [PROJECT_NOTES] AS [t1] ON 1 = 1 ГДЕ ([t1]. [NOTES] LIKE @ p0) И ([t0] .SubmittedDate]> = @ p1) И ([t0]. [SubmittedDate] <@ p2) И ([t0]. [PROVIDER_ID] = @ p3) И ([t0]. [CATEGORY_ID] НУЛЬ)) КАК [t2] ГДЕ [t2]. [ROW_NUMBER] МЕЖДУ @ 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 </p>

Этот запрос возвращает в результатах все совпадения отношения 1-много. Я нашел, как сделать Exists в LINQ отсюда. http://www.linq -to-sql.com / LINQ к SQL / T-SQL-на-Linq-обновления / LINQ-существует /

Вот LINQToSQL, использующий 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;

Сгенерированный оператор SQL:

exec sp_executesql N'SELECT COUNT (*) AS [значение] ОТ [dbo]. [ПРОЕКТЫ] КАК [t0] ГДЕ (СУЩЕСТВУЕТ (ВЫБЕРИТЕ NULL КАК [ПУСТО] ИЗ [dbo]. [PROJECT_NOTES] AS [t1] ГДЕ ([t1] .PROJECT_ID] = ([t0]. [PROJECT_ID])) И ([t1]. [ЗАМЕЧАНИЯ] LIKE @ p0))) И ([t0]. [SubmittedDate]> = @ p1) И ([t0]. [SubmittedDate] <@ p2) И ([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 </p>

Я получаю время ожидания SQL от databind() при использовании Exists.

Ответы [ 2 ]

5 голосов
/ 02 марта 2009

похоже, что возвращается несколько строк проекта

Да, так работает соединение. Если у проекта 5 совпадающих заметок, он появляется 5 раз.


Что, если проблема в том, что "Присоединиться" - неправильная идиома!

Вы хотите отфильтровать проекты к тем, чьи заметки содержат определенный текст:

var query = db.Project
  .Where(p => p.Notes.Any(n => n.NoteField.Contains(searchString)));
2 голосов
/ 02 марта 2009

Вам нужно будет использовать метод расширения DefaultIfEmpty. Уже есть несколько вопросов по SO, которые показывают, как это сделать. Вот хороший пример:

Как выполнить вложенное объединение, добавление и группирование в LINQ?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...