简体   繁体   English

使用linq过滤搜索

[英]Using linq to filter a search

I am trying to use Linq to query a database from a search user control. 我正在尝试使用Linq从搜索用户控件中查询数据库。

I have this Linq query that searches the database with a user's input. 我有这个Linq查询,它使用用户的输入来搜索数据库。

This is the code I'm currently using: 这是我当前正在使用的代码:

var query = from invite in db.invites
            where invite.Division == userInput.Division.Text &&
                  invite.Status == userInput.Status.Text
            select invite;

The problem I have is that if either one is empty I need to not take it into account for the search filter. 我的问题是,如果任何一个为空,我都无需考虑将其用作搜索过滤器。 Is there a way to do this properly, taking in consideration that I have many filters and not just status and division? 考虑到我有很多过滤器,而不仅仅是状态和划分,有没有办法正确地做到这一点?

Thanks to deferred execution you can conditionally build the query in pieces. 由于推迟执行,您可以有条件地分段构建查询。

var query = db.invites.AsQueryable();

if(!string.IsNullOrEmpty(userInput.Division.Text))
    query = query.Where(invite => invite.Division == userInput.Division.Text);

if(!string.IsNullOrEmpty(userInput.Status.Text))
    query = query.Where(invite => invite.Status== userInput.Status.Text);

This should work: 这应该工作:

var query = from invite in db.invites
        where invite.Division.Matches(userInput.Division.Text) &&
              invite.Status.Matches(userInput.Status.Text)
        select invite;

static class Extensions
{
    public static bool Matches(this string text, string value)
    {
      if(string.IsNullOrEmpty(value)) return true;
      return text == value; // or same safer comparison
    }
}

there are better ways to build queries, but this is simple (and Matches needs a better name). 有更好的方法来构建查询,但这很简单(并且Matches需要一个更好的名称)。

As @willem notes, I missed the point of query being executed on the database which seems likely ( db.invites ) - however, I am leaving the answer here as it works for Linq to Objects queries. 正如@willem指出的那样,我错过了似乎在数据库上执行查询的点( db.invites )-但是,我将答案留在这里,因为它适用于Linq to Objects查询。

var query = from invite in db.invites
        where invite.Division.Contains(userInput.Division.Text) &&
              invite.Status.Contains(userInput.Status.Text)
        select invite;

or 要么

var query = from invite in db.invites select invite;
if (!string.IsNullOrEmpty(userInput.Division.Text)) query = query.Where(invite => invite.Division == userInput.Division.Text);
if (!string.IsNullOrEmpty(userInput.Division.Text)) query = query.Where(invite => invite.Status == userInput.Status.Text);

If you want to use some extensions, I've built a library to make this a little more readable. 如果您想使用一些扩展,我已经建立了一个库来使它更具可读性。 https://www.nuget.org/packages/LinqConditionalExtensions https://www.nuget.org/packages/LinqConditionalExtensions

var hasDivision = !string.IsNullOrEmpty(userInput.Division.Text);
var hasStatus = !string.IsNullOrEmpty(userInput.Status.Text);

var query = db.Invites
    .WhereIf(hasDivision, invite => invite.Division == userInput.Division.Text)
    .WhereIf(hasStatus, invite => invite.Status == userInput.Status.Text);

You can read more about it here: https://github.com/xKloc/LinqConditionalExtensions 您可以在此处了解更多信息: https : //github.com/xKloc/LinqConditionalExtensions

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM