Левое внешнее соединение существует в Linq To SQL C# .NET 3.5
-
03-07-2019 - |
Вопрос
Я застрял на переводе левого внешнего соединения из 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]. City], [t2]. [UploadedDate], [t2]. T0]. [TITE], [T0]. [State], [T0]. . [UploadedDate], [t0]. Где ([t1]. [Примечания] как @p0) и ([t0] .submitteddate]> = @p1) и ([t0]. p3) и ([t0]. '@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
Этот запрос возвращает в результатах все кратные значения отношения «1-многие».Я нашел, как сделать Exists
в LINQ отсюда. http://www.linq-to-sql.com/linq-to-sql/t-sql-to-linq-upgrade/linq-exists/
Вот 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 (*) как [значение] из [dbo]. [проекты] как [t0] где (существует (выберите Null как [пусто] из [dbo]. t1] .project_id] = ([t0]. [project_id])) и ([t1]. . [OppertedDate] <@P2) и ([t0]. [Provider_id] =@p3) и ([t0]. DateTime,@P3 Int ',@P0 ='%Chicago%',@P1 =' '2000-09-02 00: 00: 00: 000' ',@p2 =' '2009-03-02 00:00: 00: 000 '',@p3 = 1000
Я получаю тайм-аут SQL от databind()
от использования Exists
.
Решение
кажется, он возвращает несколько строк проекта
Да, именно так работает соединение.Если в проекте есть 5 совпадающих заметок, они появятся 5 раз.
Что, если проблема в том, что «Присоединиться» — неправильная идиома!
Вы хотите отфильтровать проекты по тем, чьи заметки содержат определенный текст:
var query = db.Project
.Where(p => p.Notes.Any(n => n.NoteField.Contains(searchString)));
Другие советы
Вам придется использовать метод расширения DefaultIfEmpty.Уже есть несколько вопросов по SO, которые показывают, как это сделать.Вот хороший пример:
Как я могу выполнить вложенные операции соединения, добавления и группы в LINQ?