Левое внешнее соединение существует в Linq To SQL C# .NET 3.5

StackOverflow https://stackoverflow.com/questions/603380

Вопрос

Я застрял на переводе левого внешнего соединения из 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?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top