加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

让OData和NHibernate结合进行动态查询

发布时间:2020-12-15 21:16:42 所属栏目:asp.Net 来源:网络整理
导读:OData是一个非常灵活的RESTful API,如果要做出强大的查询API,那么OData就强烈推荐了。 OData的特点就是可以根据传入参数动态生成Entity Framework的查询,最终实现动态的SQL的查询。但是在项目有时我们并没有采用Entity Framework,而是采用的NHibernate,

OData是一个非常灵活的RESTful API,如果要做出强大的查询API,那么OData就强烈推荐了。

OData的特点就是可以根据传入参数动态生成Entity Framework的查询,最终实现动态的SQL的查询。但是在项目有时我们并没有采用Entity Framework,而是采用的NHibernate,那么该怎么用OData呢?

经过一段时间的Google和研究,终于找到了一个好的方案。

在OData API查询时,用户前端是url跟参数,但是在服务器端,我们是接收到的是一个ODataQueryOptions对象,其实我们需要做的就是把这个对象进行解析,生成NHibernate能够理解的查询形式,比如HQL。网上找到微软官方已经写了这么个转换方法,主要是对ODataQueryOptions对象下的Filter和OrderBy进行转换,另外两个参数Top和Skip很简单,就是一个整数。

???ToHql(?ODataQueryOptions?query,??top,??skip)???????{????????????queryString?=??+?query.Context.ElementClrType.Name?+??+?Environment.NewLine;????????????(query.Filter?!=?)???????????{???????????????????????????????=?ToString(query.Filter);???????????????queryString?+=?;???????????}???????????(query.OrderBy!=)???????????{??????????????????????????orderBy?=?ToString(query.OrderBy);?????????????????????????????queryString?+=??orderBy;???????????}???????????top?=?query.Top?.Value????;???????????skip?=?query.Skip?.Value????;????????????queryString;???????}?

ODataQueryOptions转换为HQL的项目在这里:

Filter和OrderBy属性都会被转换成HQL,然后我们就需要进行NHibernate的查询了。

?QueryResult?FindByPaging(?hql,??top,??skip)????????{?????????????paging?=?top?>?;?????????????query?=?Session.CreateQuery(hql);????????????querys?=?Session.CreateMultiQuery();?????????????(paging)????????????{????????????????query?=?query.SetFirstResult(skip).SetMaxResults(top);????????????}????????????querys.Add(query);??????????????????????(paging)????????????{?????????????????countQuery?=?Session.CreateQuery(?+?hql);????????????????querys.Add(countQuery);????????????}????????????queryResults?=?querys.List();?????????????result?=??QueryResult();????????????result.TotalCount?=?paging??????????????????Convert.ToInt32(?((IList)?queryResults[])[])????????????????:?((IList)?queryResults[]).Count;????????????result.ResultSet?=?((IList)?queryResults[]).Cast().ToList();?????????????result;????????}?

对于一般的分页查询来说,我们应该会有两个查询,一个是查询满足条件的数据总条数,另一个是返回当前页的数据集。但是似乎OData并不支持返回这样的数据类型,OData支持的是Entity的List,如果我们重新定义了一个对象QueryResult:

[DataContract]?????QueryResult???{???????[DataMember]?????????TotalCount?{?;?;?}???????[DataMember]????????IList?ResultSet?{?;?;?}????????QueryResult()???????{?}????????QueryResult(?count,?IList?list)???????{???????????.TotalCount?=?count;???????????.ResultSet?=?list;???????}???}?

然后在Controller中返回QueryResult,那么系统就会报406的错误。其实系统给我们提供了一个专门分页返回的对象,我们可以将Service返回的QueryResult封装成PageResult再返回即可。

PageResult里面有个NextPage的URI参数,我们可以传Null。?

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读