我有一个包含许多记录的表,可以通过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();
答案 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();