在LINQ查询'where'语句中实现条件'if'语句

And*_*ans 15 c# linq

我试图找出一种在我的数据模型中查询对象的方法,并且只包括那些非空的参数.如下所示:

public List<Widget> GetWidgets(string cond1, string cond2, string cond3)
{
    MyDataContext db = new MyDataContext();
    List<Widget> widgets = (from w in db.Widgets
                            where 
                                ... if cond1 != null w.condition1 == cond1 ...
                                ... if cond2 != null w.condition2 == cond2 ...
                                ... if cond3 != null w.condition3 == cond3 ...
                            select w).ToList();
    return widgets;
}
Run Code Online (Sandbox Code Playgroud)

由于小部件表可能变得非常大,我想避免这样做:

public List<Widget> GetWidgets(string cond1, string cond2, string cond3)
{
    MyDataContext db = new MyDataContext();
    List<Widget> widgets = db.Widgets.ToList();

    if(cond1 != null)
        widgets = widgets.Where(w => w.condition1 == cond1).ToList();

    if(cond2 != null)
        widgets = widgets.Where(w => w.condition2 == cond2).ToList();

    if(cond3 != null)
        widgets = widgets.Where(w => w.condition3 == cond3).ToList();

    return widgets;
}
Run Code Online (Sandbox Code Playgroud)

我看了几个例子,但没有看到任何符合我需要做的事情.

Fre*_*örk 32

您要避免的是实际执行查询,直到您准备好:

public List<Widget> GetWidgets(string cond1, string cond2, string cond3)
{
    MyDataContext db = new MyDataContext();
    var widgets = db.Widgets;

    if(cond1 != null)
        widgets = widgets.Where(w => w.condition1 == cond1);

    if(cond2 != null)
        widgets = widgets.Where(w => w.condition2 == cond2);

    if(cond3 != null)
        widgets = widgets.Where(w => w.condition3 == cond3);

    return widgets.ToList();
}
Run Code Online (Sandbox Code Playgroud)

请注意如何ToList删除呼叫.在您开始迭代之前,不会执行查询.调用ToList将强制发生这种情况,以便将结果放入List<>并返回.我甚至建议将方法的返回值更改为IEnumerable<Widget>ToList最终跳过调用:

public IEnumerable<Widget> GetWidgets(string cond1, string cond2, string cond3)
{
    MyDataContext db = new MyDataContext();
    var widgets = db.Widgets;

    if(cond1 != null)
        widgets = widgets.Where(w => w.condition1 == cond1);

   // [...]

    return widgets;
}
Run Code Online (Sandbox Code Playgroud)

这样调用代码就可以决定何时执行查询(甚至可以在执行此操作之前添加更多条件).


小智 23

使用"或门":在每个小部件条件测试前加上"||" 并检查我们是否正在使用该条件.如果我们不是,那么"或"的后半部分不会被评估.这就是为什么它是一个门 - 如果第一部分评估为真,我们就不会再进一步​​了.

如果我正在写它,我会像下面这样做.我使用var syntatic sugar来保存LINQ查询并将ToList()移动到最后.

public List<Widget> GetWidgets(string cond1, string cond2, string cond3) 
{ 
    MyDataContext db = new MyDataContext(); 
    var widgets = from w in db.Widgets 
                  where (cond1 == null || w.condition1 == cond1)
                     && (cond2 == null || w.condition2 == cond2)
                     && (cond3 == null || w.condition3 == cond3)
                  select w;
    return widgets.ToList();
} 
Run Code Online (Sandbox Code Playgroud)

编辑:语法