LINQ条件Where子句不起作用

时间:2015-08-04 23:38:59

标签: c# linq entity-framework entity-framework-6

使用:MVC 5,C#,VS 2013,EF6和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个过滤器,我会得到我想要的数据。一旦我提供了超过1个过滤器,我得到“枚举没有产生结果”,但第一个过滤器的数据集确实包含我正在过滤的数据。

4 个答案:

答案 0 :(得分:7)

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

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

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

试试这个:

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

虽然这并不能解释为什么你没有得到任何结果。当你得到正确的代码时,这将是一个你应该解决的问题。

答案 1 :(得分:1)

您可以尝试使用谓词构建器(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;}
}

答案 2 :(得分:1)

哇,我无法相信我的问题是什么问题/解决方案。因为我在.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"

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

感谢大家提供解决方案。

答案 3 :(得分:1)

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

class Program
    {
        static void Main(string[] args)
        {
            var testList = new List<Test>();
            testList. Add(new Test() { Field4 = false, Field1 = 19845623, Field3 = 1658006 });
            testList.Add(new Test() { Field4 = false, Field1 = 19845645, Field3 = 1658056 });
            testList.Add(new Test() { Field4 = false, Field1 = 19845665, Field3 = 1658045 });
            testList.Add(new Test() { Field4 = false, Field1 = 19845678, Field3 = 1658078 });
            testList.Add(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; }
    }

希望这会有所帮助!