使用多个过滤器值过滤数据

时间:2014-06-16 19:53:28

标签: c# sql entity-framework filtering repeater

你好伙伴stackoverflowers,

我目前正在开展一个项目,通过使用多个过滤器值,我在使用数据库过滤数据方面遇到了一些麻烦。选择过滤器并单击按钮后会发生过滤。

我有5个过滤器:Region,Company,Price和2个布尔值
请注意,Region和Company是特殊的下拉列表,带有复选框,这意味着用户可以选择一个或多个地区和公司名称。

我已经做了一些测试,并提出了一个不完整的代码,但有点但不符合我的喜好。

当我的某个过滤器为NULL或为空时出现问题。我真的不知道如何处理这个问题。我想到的唯一方法是使用一堆IF ELSE语句,但我开始认为这种情况永远不会结束,因为有太多的可能性......

我确信在不使用一堆IF ELSE语句的情况下更容易实现这一点,但我真的不知道该怎么做。如果有人能引导我朝正确的方向前进,那将是值得赞赏的。感谢

以下是我现在的情况(我现在还没有将价格添加到查询中):

protected void filterRepeater(List<int> regionIDs, string[] companyArray,
    string blocFiltValue, bool bMutFunds, bool bFinancing)
{
    DatabaseEntities db = new DatabaseEntities();
    PagedDataSource pagedDsource = new PagedDataSource();

    IQueryable<Blocs> query = (from q in db.Blocs
                               where q.isActive == true
                               orderby q.date descending
                               select q);
    IQueryable<Blocs> queryResult = null;

    //if some filters are NULL or Empty, it create a null queryResult
    queryResult = query.Where(p => companyArray.Contains(p.company) &&
                                   regionIDs.Contains((int)p.fkRegionID) &&
                                   (bool)p.mutual_funds == bMutFunds &&
                                   (bool)p.financing == bFinancing);

    if (queryResult.Count() > 0)
    {
        //Bind new data to repeater
        pagedDsource.DataSource = queryResult.ToArray();
        blocRepeater.DataSource = pagedDsource;
        blocRepeater.DataBind();
    }
}

3 个答案:

答案 0 :(得分:2)

仅将相关过滤条件添加到query

IQueryable<Blocs> query =
    from q in db.Blocs
    where q.isActive == true
    orderby q.date descending
    select q;

if (companyArray != null)
{
    query = query.Where(p => companyArray.Contains(p.company));
}

if (regionIDs != null)
{
     query = query.Where(p => regionIDs.Contains((int)p.fkRegionID));
}

// ...
// etc
// ...

if (query.Any()) // Any() is more efficient than Count()
{
    //Bind new data to repeater
    pagedDsource.DataSource = query.ToArray();
    blocRepeater.DataSource = pagedDsource;
    blocRepeater.DataBind();
}

答案 1 :(得分:1)

如果只想通过非空或空的过滤器值进行过滤,则可以通过逐个附加where子句来构造查询:

if(companyArray != null && companyArray.Length > 0) {
    query = query.Where(p => companyArray.Contains(p.company));
}
if(regionIDs!= null && regionIDs.Length > 0) {
    query = query.Where(p => regionIDs.Contains((int)p.fkRegionID));
}
if (!String.IsNullOrEmpty(blocFiltValue)) {
    query = query.Where(p => p.Block == blocFiltValue);
}

如果您需要可选地过滤它们,也可以为值类型使用可空值

bool? bMutFunds = ...; // Possible values: null, false, true.

...

if(bMutFunds.HasValue) {
    query = query.Where(p => (bool)p.mutual_funds == bMutFunds.Value); 
}

答案 2 :(得分:0)

也许你可以为SQL语句创建一个字符串,并动态地为这句话添加部分,就像选择或检查某些内容一样,当用户完成选择后你可以执行这个SQL语句时,你可以在这个字符串中添加一些内容。 / p>