动态Linq查询帮助?

时间:2011-10-22 21:24:11

标签: c# asp.net-mvc linq

如何针对以下简单搜索条件编写动态Linq查询? 1)学生编号 2)姓氏 3)LastName和FirstName

//if (!String.IsNullOrEmpty(StudentNumber))
var results  = (from s in Students              
                where s.StudentNumber == 1001
                select s
               );

//else if (!String.IsNullOrEmpty(LastName) & (String.IsNullOrEmpty(FirstName))

var results  = (from s in Students              
                where s.LastName == "Tucker"
                select s
               );

//else if (!String.IsNullOrEmpty(LastName) & (!String.IsNullOrEmpty(FirstName))            
var results  = (from s in Students              
                where s.LastName == "Tucker" && s.FirstName == "Ron"
                select s
               );   

1 个答案:

答案 0 :(得分:5)

您需要在任何单个查询之外声明results变量。这样您就可以根据不同的条件添加不同的过滤器,并根据需要添加尽可能多的过滤器。一个例子:

var results = Students.AsEnumerable(); // use .AsQueryable() for EF or Linq-to-SQL

if (!string.IsNullorEmpty(StudentNumber)) 
{
    results = results.Where(s => s.StudentNumber.Equals(StudentNumber));
}
else if (!string.IsNullOrEmpty(LastName))
{
    results = results.Where(s => s.LastName.Equals(LastName));

    if (!string.IsNullOrEmpty(FirstName))
    {
         results = results.Where(s => s.FirstName.Equals(FirstName));
         // filter is in addition to predicate against LastName
    }
}

// results can be used here

如果处理Linq-to-Entities或-Sql,请使用Students.AsQueryable();键入初始查询,以便过滤在数据库而不是应用程序内部进行。


  

有没有办法可以先构造WHERE子句并在一个中使用它   Linq查询没有if ... else

如果要在查询的第一步之前构建整个where,则它是相同的逻辑。您有条件地构建谓词,因此您将涉及某种if / else。但是,要首先构建整个谓词,可以针对Linq to Objects构建Func<Student, bool>

Func<Student, bool> predicate;
if (!string.IsNullOrEmpty(StudentNumber))
{
    predicate = s => s.StudentNumber.Equals(StudentNumber);
}
else if (!string.IsNullOrEmpty(LastName))
{
    predicate = s => s.LastName.Equals(LastName);

    if (!string.IsNullOrEmpty(FirstName))
    {
        Func<Student, bool> p = predicate;
        predicate = s => p(s) && s.FirstName.Equals(FirstName);
    }
}
else
{
    predicate = s => true;
}

var query = Students.Where(predicate);

您会注意到if / else结构完全相同。您可以将其折叠成复杂的条件表达式

Func<Student, bool> predicate;
predicate = s =>
    !string.IsNullOrEmpty(StudentNumber)
    ? s.StudentNumber.Equals(StudentNumber)
    : !string.IsNullOrEmpty(LastName)
        ? !string.IsNullOrEmpty(FirstName)
            ? s.LastName.Equals(LastName) && s.FirstName.Equals(FirstName)
            : s.LastName.Equals(LastName)
        : true;

var query = Students.Where(predicate);

但是我觉得很难遵循,当然比较长的if / else。这个谓词也比我们通过if / else构建的谓词更大,因为这个谓词包含 all 逻辑,它不仅仅是我们有条件地添加的逻辑。