2013-09-12 2 views
0

Что такое эквивалент LINQ запрос на следующий запрос SQL:Выберите ВВыберите Заявление

Select Id, Name 
From Table1 tbl1 
Where Id in (Select Id From Table2) 
+0

LINQ является частью C#, заявление, которое вы указали, является SQL. Если вы пытаетесь выбрать данные на C#, вам нужны данные в объекте C#, а не в базе данных. Как вы это делаете; LINQ to SQL? Entity Framework? ADO.NET? –

+0

Entity Framework на языке C# – ehsan

ответ

1

попробуйте использовать Contains метод:

var query = from c in db.Table1 
      where db.Table2.Select(x => x.Id).Contains(c.Id) 
      select new { c.Id, c.Name }; 

var result = query.ToList(); 
+0

имеет ли он n * m сложность? –

+1

@IlyaIvanov В теории да, и если бы это было linq для объектов, это было бы ужасно ужасно. На практике это будет переведено на SQL, очень похожее на код в OP, а механизм DB достаточно умен, чтобы оптимизировать это в более правильный алгоритм, такой как ваш, внутренне, тем самым предотвращая его от ужаса. (По крайней мере, в теории, это должно быть проверено с вашим конкретным поставщиком запросов и базой данных, чтобы быть уверенным.) Имея надлежащие индексы на столбцах, здесь также большое дело. – Servy

+0

@Servy Я только что пробовал этот код с EF и MSSQL, он создает '... WHERE EXISTS (SELECT NULL AS [EMPTY] FROM Table2 AS t2 WHERE t1.Id = t2.Id)'. Вы уверены, что это будет оптимизировано движком? (спрашиваю, потому что я не уверен в этом) –

3

Вы в основном описал внутреннее соединение с выбором строк из одна таблица:

var result = from t1 in Table1 
      join t2 in Table2 
      on t1.Id equals t2.Id 
      select new{t1.Id, t1.Name}; 

Следующая инструкция SQL будет сгенерирована с использованием EF и MS SQ L:

SELECT t1.Id, t1.Name 
FROM Table1 AS t1 
INNER JOIN Table2 AS t2 ON t1.Id = t2.Id 

Обратите внимание, что если вы выбираете, не уникальные предметы из Table2, вы потенциально можете иметь дубликаты в result. Используйте следующий запрос, чтобы избежать этой проблемы, минусы: он загружает все идентификаторы из Таблицы 2 в память, профи: более эффективное время. Checkout Felipes отвечает, что тоже неплохо, но имеет свои собственные недостатки, обсуждаемые в разделе комментариев.

var table2Ids = new HashSet<int>(context.Table2.Select(t2 => t2.Id)); 

var result = context.Table1 
        .Where(t => table2Ids.Contains(t.Id)) 
        .Select(t => new{t.Id, t.Name}); 
+0

Обратите внимание, что технически это должно быть левое внутреннее соединение, а не внутреннее соединение. Результаты будут отличаться для вашего кода, если заданное значение «Id» существует во второй таблице дважды. – Servy

+0

@Servy почему ушел? 'Where Id in (Select Id From Table2)' должен возвращать false, если id отсутствует в правой таблице, если я не ошибаюсь –

+0

Правильно, если идентификатор отсутствует во второй таблице, оба запроса правильно исключают эту строку , Если во второй таблице есть одна строка с одинаковым идентификатором в первом, оба запроса возвращают одинаковое значение для этого идентификатора. Если заданный ID в первой таблице появляется два, три или более раз во второй таблице, запрос OP возвращает это значение идентификатора один раз, ваш запрос возвращает это значение ID N раз, один раз для каждого совпадения. Возможно, это может быть проблемой. Вы можете дополнительно его фильтровать, но проще всего просто выполнить групповое соединение и просто выбрать элемент первой таблицы. – Servy

Смежные вопросы