LINQ条件Where子句不起作用

本文关键字:不起作用 子句 Where 条件 LINQ | 更新日期: 2023-09-27 18:06:18

使用:MVC 5, c#, VS 2013, EF6 with CodeFirst, SQL Server 2012

我已经尝试了四种不同的方法来获得数据,没有任何问题。

IQueryable<vw_Results> qryResults = _db.vw_Results;

我遇到的问题是,我有13个过滤器选项和所有13的代码遵循相同的逻辑:

string fmVal = string.Empty;
if (!string.IsNullOrEmpty(form["Locations"]))
{
    fmVal = form["Locations"].ToString();
    qryResults = qryResults.Where(w => w.LOCATION.CompareTo(fmVal) == 0);
}
if (!string.IsNullOrEmpty(form["ddActionLevels"]))
{
    //qryResults = qryResults.Where(w => w.PAL_ID==form["ddActionLevels"].ToString());
    vbVal = form["ddActionLevels"].ToString(); ;
    //qryResults = qryResults.Where(w => w.AL == vbVal);
    qryResults.Where(w => w.AL.CompareTo(vbVal) >= 0);
}
if (!string.IsNullOrEmpty(form["btnGenericRpt"]))
{
    qryResults.Where(w => w.LOCATION != "BB1");
}
if (!string.IsNullOrEmpty(form["ddProjects"]))
{
    vbVal = form["ddProjects"].ToString();
    qryResults.Where(w => w.PROJECT == vbVal);
}
//...
myModel.Results = qryResults.ToList();
return View(myModel);

如果我只提供一个过滤器,我得到我想要的数据。一旦我提供了超过1个过滤器,我就会得到"Enumeration没有产生结果",但是来自第一个过滤器的数据集确实包含了我要过滤的数据。

LINQ条件Where子句不起作用

我看到你的代码的主要问题是这样的行:

qryResults.Where(w => w.AL.CompareTo(vbVal) >= 0);

您从qryResults开始,计算.Where(...),但您不会将查询重新分配回qryResults

试试这个:

qryResults = qryResults.Where(w => w.AL.CompareTo(vbVal) >= 0);

虽然这并不能解释为什么你没有得到任何结果。当你写好代码后,你应该解决这个问题。

为了获得过滤后的数据并从那里工作,我需要在Where之后添加.ToList()并进一步分配过滤后的结果:

class Program
{
    static void Main(string[] args)
    {
        var testList = new List<Test>()
        {
            new Test() { Field4 = false, Field1 = 19845623, Field3 = 1658006 },
            new Test() { Field4 = false, Field1 = 19845645, Field3 = 1658056 },
            new Test() { Field4 = false, Field1 = 19845665, Field3 = 1658045 },
            new Test() { Field4 = false, Field1 = 19845678, Field3 = 1658078 },
            new Test() { Field4 = false, Field1 = 19845698, Field3 = 1658098 },
        };
        var test = testList.Where(x => x.Field4 == false).ToList();
        Console.WriteLine();
    }
}
internal class Test
{
    public int Field1 { get; set; }
    public long Field3 { get; set; }
    public bool Field4 { get; set; }
}

希望这是有帮助的!

您可以尝试使用predicatebuilder (ref http://blogs.msdn.com/b/meek/archive/2008/05/02/linq-to-entities-combining-predicates.aspx)来基于不同的if语句为where子句构建表达式,然后在最后对qryResults使用它,而不是像代码展示那样使用多个where子句。

下面是一个如何使用predicateBuilder的示例

void Main()
{
    var myQuery = new List<Car> { 
        new Car {IsRed = true, IsConvertible = true },
        new Car {IsRed = true, IsConvertible = false },
        new Car {IsRed = false, IsConvertible = true },
        new Car {IsRed = false, IsConvertible = false }
    }.AsQueryable();
    Expression<Func<Car, bool>> isRed = c => c.IsRed;
    Expression<Func<Car, bool>> isConvertible = c => c.IsConvertible;
    var isRedConvertible = isRed.And(isConvertible);
    var redConvertible = myQuery.Where(isRedConvertible);
}
public class Car
{
    public bool IsRed {get;set;}
    public bool IsConvertible {get;set;}
}

哇,我简直不敢相信我的问题/解决方案是什么。因为我在。where子句中使用相同的变量(vbVal),当获取数据的时候,查询使用vbVal的最后一个值,因此不返回任何数据。我猜LINQ使用ByRef变量,所以我的查询将结束为:

vbVal = form["filter1"]; {"North America"}
qryResults = qryResults.Where (w=>w.col1 == vbVal);
vbVal = form["filter2"]; {"USA"}
qryResults = qryResults.Where (w=>w.col2 == vbVal);
vbVal = form["filter3"]; {"New York"}
qryResults = qryResults.Where (w=>w.col2 == vbVal);

返回到SQL的查询将是:

Select col1, col2, col3 From dbTable 
Where col1 = "New York" and col2 = "New York" and col3 = "New York"

将每个过滤器选项分配给一个唯一的变量解决了我的问题。

感谢大家提供的解决方案。