博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
让OData和NHibernate结合进行动态查询
阅读量:5807 次
发布时间:2019-06-18

本文共 2379 字,大约阅读时间需要 7 分钟。

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

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

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

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

public 
static 
string ToHql(
this ODataQueryOptions query,
out 
int top,
out 
int skip) 
      { 
          
string queryString = 
"
from 
" + query.Context.ElementClrType.Name + 
"
 $it
" + Environment.NewLine; 
          
if (query.Filter != 
null
          { 
              
//
 convert $filter to HQL where clause. 
              
string 
where = ToString(query.Filter); 
              queryString += 
where
          } 
          
if(query.OrderBy!=
null
          { 
          
//
 convert $orderby to HQL orderby clause. 
              
string orderBy = ToString(query.OrderBy);
              
//
 create a query using the where clause and the orderby clause. 
               queryString +=  orderBy; 
          } 
          top = query.Top?.Value ?? 
0
          skip = query.Skip?.Value ?? 
0
          
return queryString; 
      } 

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

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

public QueryResult<T> FindByPaging(
string hql, 
int top, 
int skip) 
       { 
           
bool paging = top > 
0
           
var query = Session.CreateQuery(hql);
           
var querys = Session.CreateMultiQuery(); 
           
if (paging) 
           { 
               query = query.SetFirstResult(skip).SetMaxResults(top); 
           } 
           querys.Add(query); 
         
           
if (paging) 
           { 
               
var countQuery = Session.CreateQuery(
"
select count(*) 
" + hql); 
               querys.Add(countQuery); 
           }
           
var queryResults = querys.List(); 
           
var result = 
new QueryResult<T>(); 
           result.TotalCount = paging 
               ? Convert.ToInt32( ((IList) queryResults[
1])[
0]) 
               : ((IList) queryResults[
0]).Count; 
           result.ResultSet = ((IList) queryResults[
0]).Cast<T>().ToList(); 
           
return result; 
       } 

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

[DataContract] 
  
public 
class QueryResult<T> 
  { 
      [DataMember] 
      
public 
int TotalCount { 
get
set; } 
      [DataMember] 
      
public IList<T> ResultSet { 
get
set; } 
      
public QueryResult() 
      { } 
      
public QueryResult(
int count, IList<T> list) 
      { 
          
this.TotalCount = count; 
          
this.ResultSet = list; 
      } 
  } 

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

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

本文转自深蓝居博客园博客,原文链接:http://www.cnblogs.com/studyzy/p/5462868.html,如需转载请自行联系原作者

你可能感兴趣的文章
kafka_2.11-0.8.2.1单机版安装
查看>>
Linux目录结构及用途
查看>>
钩针纺织资料
查看>>
队列的实现
查看>>
SWFUpload使用指南
查看>>
所谓厉害的人,遇到问题时的思维模式与我们的差别在哪?(转自知乎)
查看>>
amazeui的表单开关插件的自定义事件必须添加.bootstrapSwitch 命名空间,给了我们什么启示...
查看>>
poj 2104 K-th Number 主席树+超级详细解释
查看>>
乐透TV:php 优酷视频采集,小示例(基于phpquery)
查看>>
企业架构研究总结(37)——TOGAF企业连续体和工具之架构资源库及架构工具的选择...
查看>>
Openstack_通用模块_Oslo_vmware 创建 vCenter 虚拟机快照
查看>>
方法编写经验总结
查看>>
Redis学习笔记(1)-Key
查看>>
头条笔试题 分配任务
查看>>
数据库知识
查看>>
走出浮躁的泥沼:浮躁的社会原因
查看>>
SQL-20 查找员工编号emp_no为10001其自入职以来的薪水salary涨幅值growth
查看>>
【哈希表】Ural Championship April 30, 2017 Problem H. Hamburgers
查看>>
JS作用域理解(声明提升)
查看>>
Tomcat 系统架构与设计模式
查看>>