构建可选过滤器的标准列表,用于检索记录nhibernate c#

时间:2013-05-30 13:13:53

标签: linq c#-4.0 fluent-nhibernate criteria nhibernate-criteria

我有一个包含许多记录的表,可以通过rowstatus,创建日期,修改日期进行过滤。

我使用流利的nhibernate作为ORM。

现在WebAPi中的请求可以是:

?rowstatus = 0 要么 ?rowstatus = 0&安培; createddate = 2013年5月30日 要么 createddate = 2013年5月30日 要么 modifieddate = 2013年5月29日&安培; rowsstatus = 0

正如您所见,任何过滤器组合都可以进入查询字符串。

我想知道,如何动态构建一个条件列表并将其提供给我的ISession对象来执行。什么是最好的方法。

目前我有这么多重载函数来做它并且它很难看。这是我正在使用的一个例子。我想动态注入rowstatus和createddate。

_session.QueryOver<ApiData>()
                           .Where(a => (a.status== rowstatus)
                                       && (a.createdDate== createddate)).List().ToList();

2 个答案:

答案 0 :(得分:1)

我对这种类型的场景使用nHibernate Criteria查询,因为它们非常灵活,您可以根据所提供的搜索参数随意构建它们。

我已根据您在问题中指定的一些条件为您创建了一个基本示例,您应该能够修改我的示例以满足您的特定需求。

public IList<ApiData> SearchApiData(int? rowStatus, DateTime? createdDate)
{

        ICriteria query = _session.CreateCriteria<ApiData>();

        if (rowStatus.HasValue)
        {
            query.Add(Restrictions.Eq("RowStatus", rowStatus.Value));
        }

        if (createdDate.HasValue)
        {
            query.Add(Restrictions.Eq("CreatedDate", createdDate.Value));
        }

        return query.List<ApiData>();

}

此外,当我有很多搜索参数时,我通常会创建一个类结构,以便在我的应用程序中传递它们,例如:

public class ApiDataCriteria{

     public int? RowStatus {get;set;}
     public DateTime? Created {get;set;}
     public DateTime? Modified {get;set;}

}

根据您当前的搜索条件填充此内容(很可能是基于UI中的用户选择),然后将其传递到我在上面创建的方法,如下所示:

public IList<ApiData> SearchApiData(ApiDataCriteria criteria)
{

        ICriteria query = _session.CreateCriteria<ApiData>();

        if (criteria.rowStatus.HasValue)
        {
            query.Add(Restrictions.Eq("RowStatus", criteria.rowStatus.Value));
        }

        if (criteria.createdDate.HasValue)
        {
            query.Add(Restrictions.Eq("CreatedDate", criteria.createdDate.Value));
        }

        return query.List<ApiData>();

}

这样,您只需要一个方法,即使您稍后添加更多搜索条件,其签名也不会改变。

答案 1 :(得分:0)

这就是我最终做到的:

        var status = queryParams.FirstOrDefault(q => q.Key == "status").Value;
        var entity = queryParams.FirstOrDefault(q => q.Key == "entity").Value;
        var start = queryParams.FirstOrDefault(q => q.Key == "start").Value;

        if(!string.IsNullOrEmpty(status))
        {
            query.Where(r => r.RowStatus == Convert.ToInt32(status));
        }
        if (!string.IsNullOrEmpty(entity))
        {
            query.Where(r => r.EntityType == entity);
        }

        //Ensure that this should be the last filter criteria to be applied
        if (!string.IsNullOrEmpty(start))
        {
            query.Skip(Convert.ToInt32(start));
        }

        var count = query.RowCount();

        var results = query.Take(apiUser.ApiLimit).List().Select(c => _cryptography.Decrypt(c.Json)).ToList();