1

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

我正在使用流利的 nhibernate 作为 ORM。

现在可以进入 WebAPi 的请求可以是:

?rowstatus=0 或 ?rowstatus=0&createddate=05-30-2013 或 createddate=05-30-2013 或 modifieddate=05-29-2013&rowsstatus=0

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

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

目前我有这么多的重载函数来做这件事,而且很难看。这是我正在使用的示例。我想动态注入rowstatus和createddate。

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

2 回答 2

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>();

}

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

于 2013-05-30T20:01:02.200 回答
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();
于 2013-05-30T22:41:10.940 回答