Я хочу генерировать этот SQL-оператор в LINQ:
select * from Foo where Value in ( 1, 2, 3 )
Хитрый бит, кажется, что Значение является столбцом, который позволяет, аннулирует.
Эквивалентный код LINQ, казалось бы, был бы:
IEnumerable<Foo> foos = MyDataContext.Foos;
IEnumerable<int> values = GetMyValues();
var myFoos = from foo in foos
where values.Contains(foo.Value)
select foo;
Это, конечно, не компилирует с тех пор foo.Value
int?
и values
вводится к int
.
Я попробовал это:
IEnumerable<Foo> foos = MyDataContext.Foos;
IEnumerable<int> values = GetMyValues();
IEnumerable<int?> nullables = values.Select( value => new Nullable<int>(value));
var myFoos = from foo in foos
where nullables.Contains(foo.Value)
select foo;
... и это:
IEnumerable<Foo> foos = MyDataContext.Foos;
IEnumerable<int> values = GetMyValues();
var myFoos = from foo in foos
where values.Contains(foo.Value.Value)
select foo;
Обе из этих версий дают мне результаты, которые я ожидаю, но они не генерируют SQL, который я хочу. Кажется, что они генерируют результаты полной таблицы и затем делают Содержание () фильтрация в оперативной памяти (т.е.: в простом LINQ, без - к SQL); существует нет IN
пункт в журнале DataContext.
Существует ли способ генерировать SQL В для типов Nullable?
Как оказалось, проблема, которую я имел, не имела ничего, чтобы сделать Contains или Nullable, и таким образом, формулировка моего вопроса в основном не важна. См. принятый ответ @Nick Craver для деталей.
Это должно работать для вашего примера:
IEnumerable<int> values = GetMyValues();
var myFoos = from foo in MyDataContext.Foos;
where values.Contains(foo.Value.Value)
select foo;
Приведение как IEnumerable
с самого начала означает, что выполнение будет вне SQL, вместо этого вызовите IQueryable
напрямую. Если вы приведете как IEnumerable
и используете его в запросе, он получит все MyDataContext.Foos
, затем использует этот итератор и выполнит остальную часть запроса на C # вместо SQL.
Если вы хотите работать в SQL, не приводите его к IEnumerable
где-либо по пути. Эффект такой же, как при использовании MyDataContext.Foos.AsEnumerable ()
в запросе.