【问题标题】:LINQ-to-SQL IN/Contains() for Nullable<T>Nullable<T> 的 LINQ-to-SQL IN/Contains()
【发布时间】:2010-03-12 17:58:05
【问题描述】:

我想在 LINQ 中生成这条 SQL 语句:

select * from Foo where Value in ( 1, 2, 3 )

棘手的一点似乎是 Value 是一个允许空值的列。

等效的 LINQ 代码似乎是:

IEnumerable<Foo> foos = MyDataContext.Foos;
IEnumerable<int> values = GetMyValues();
var myFoos = from foo in foos
             where values.Contains(foo.Value)
             select foo;

这当然不能编译,因为foo.Valueint?,而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。看来他们正在生成全表结果,然后在内存中进行 Contains() 过滤(即:在普通 LINQ 中,没有 -to-SQL); DataContext 日志中没有 IN 子句。

有没有办法为 Nullable 类型生成 SQL IN?

注意

事实证明,我遇到的问题与 Contains 或 Nullable 无关,因此我的问题的措辞在很大程度上是无关紧要的。有关详细信息,请参阅@Nick Craver 接受的答案。

【问题讨论】:

    标签: sql linq linq-to-sql nullable


    【解决方案1】:

    这应该适用于您的示例:

    IEnumerable<int> values = GetMyValues();
    var myFoos = from foo in MyDataContext.Foos;
                 where values.Contains(foo.Value.Value)
                 select foo;
    

    从一开始就转换为IEnumerable&lt;T&gt; 意味着执行将在SQL 之外,而是直接调用IQueryable&lt;Foo&gt;。如果您转换为 IEnumerable 并在查询中使用它,它将获取所有 MyDataContext.Foos 然后使用该迭代器并在 C# 中而不是在 SQL 中执行查询的其余部分。

    如果您想在 SQL 中运行,请不要在此过程中的任何地方强制转换为 IEnumerable。效果和查询中使用MyDataContext.Foos.AsEnumerable()一样。

    【讨论】:

    • 哇,我没有意识到转换引用会产生影响(无疑是由于使用了特定类型的扩展方法)。从 OOP 的角度来看,这是不幸的。但是,它确实解决了我的问题。谢谢!
    猜你喜欢
    • 2010-11-20
    • 1970-01-01
    • 2011-03-04
    • 2011-01-23
    • 2011-01-20
    • 1970-01-01
    • 2011-06-16
    • 1970-01-01
    • 2010-10-25
    相关资源
    最近更新 更多