动态Linq查询帮助?

rk1*_*962 1 c# linq asp.net-mvc

如何为以下简单搜索条件编写动态Linq查询?1)StudentNumber 2)LastName 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
               );   
Run Code Online (Sandbox Code Playgroud)

Ant*_*ram 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
Run Code Online (Sandbox Code Playgroud)

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


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

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

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);
Run Code Online (Sandbox Code Playgroud)

您会注意到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);
Run Code Online (Sandbox Code Playgroud)

但我发现很难遵循,当然与if/else相比更长.这个谓词也比我们通过if/else构建的谓词更大,因为这个谓词包含所有逻辑,它不仅仅是我们有条件地添加的逻辑.