好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

CQRS:CQRS+AJAX架构 之 查询(Q)模型设计

CQRS:CQRS+AJAX架构 之 查询(Q)模型设计

CQRS:CQRS+AJAX架构 之 查询(Q)模型设计

背景

准备采用CQRS架构,之前也简单的应用过(只是把读和写在程序级别进行了分离),这篇文章是我最近几天的思考,写下来希望大家多提意见。这篇文章不会涉及Command端的设计,重点关注如何设计查询。

真心的希望大家看完后能给出你们的意见和想法。

什么是CQRS CQRS:Command Query Responsibility Separation。我喜欢职责分离,这也是我采用这种架构的原因,确实能带来单一职责的优点。

简单的CQRS

复杂的CQRS

CQRS的常见查询需求

下面是系统的一些查询需求:

查询面板

高级查询

数据行级别的权限

如:个人、部门、分公司、品种。

固定约束

如:启用、合法、租户ID。

需求总结

CQRS的查询设计 充分利用SQL和动态类型的优势,不做太多无谓的封装。

关键决策: 直接查询数据库返回Dynamic类型,不需要定义强类型。 直接用SQL,支持动态查询面板和动态数据行权限。目前没有找到封装SQL的理由,最多是在外围再封装一层,但是不会隐藏SQL(我之前写过一个简单的查询对象)。 利用一些策略防止SQL注入和权限提升(这篇文章不介绍)。

示例代码

下载地址: http://happy.codeplex.com/SourceControl/latest 。

AJAX程序

  1   //  / <reference path="Ext/ext-all-debug-w-comments.js" /> 
  2  
  3  Ext.onReady( function   () {
   4       var  query =  {
   5          TableOrViewName: 'Users' ,
   6          WhereClause: "Name NOT LIKE '%段%'"
  7       };
   8  
  9       Ext.Ajax.request({
  10          url: 'TestDynamicQuery/Fetch' ,
  11          method: 'POST' ,
  12           params: { query: Ext.encode(query) },
  13          success:  function   (response) {
  14               console.log(response.responseText);
  15           }
  16       });
  17  
 18      query =  {
  19          TableOrViewName: 'Users' ,
  20          WhereClause: "Age >= 20 AND Age <= 27"
 21       };
  22  
 23       Ext.Ajax.request({
  24          url: 'TestDynamicQuery/Fetch' ,
  25          method: 'POST' ,
  26           params: { query: Ext.encode(query) },
  27          success:  function   (response) {
  28               console.log(response.responseText);
  29           }
  30       });
  31  });

万能查询控制器

  1   using   System;
   2   using   System.Collections.Generic;
   3   using   System.Linq;
   4   using   System.Text;
   5   using   System.Threading.Tasks;
   6   using   System.Web.Mvc;
   7  
  8   using   Newtonsoft.Json;
   9  
 10   using   Happy.Query;
  11  
 12   namespace   Happy.Web.Mvc
  13   {
  14       ///   <summary> 
 15       ///   动态查询控制器。
  16       ///   </summary> 
 17       public   abstract   class  DynamicQueryController<TDynamicQueryService>  : AjaxController
  18           where   TDynamicQueryService : IDynamicQueryService
  19       {
  20           ///   <summary> 
 21           ///   动态查询服务。
  22           ///   </summary> 
 23           protected   abstract  TDynamicQueryService QueryService {  get  ; }
  24  
 25           ///   <summary> 
 26           ///   获取分页数据,面向表格。
  27           ///   </summary> 
 28           public   ActionResult Page(DynamicQueryObject query)
  29           {
  30               var  result =  this  .QueryService.Page(query);
  31  
 32               return   this  .Json(result);
  33           }
  34  
 35           ///   <summary> 
 36           ///   获取列表数据,面向不需要分页的表格或下拉框。
  37           ///   </summary> 
 38           public   ActionResult Fetch(DynamicQueryObject query)
  39           {
  40               var  result =  this  .QueryService.Fetch(query);
  41  
 42               return   this  .NewtonsoftJson(result);
  43           }
  44  
 45           ///   <summary> 
 46           ///   获取一个数据,面向表单。
  47           ///   </summary> 
 48           public   ActionResult SingleOrDefault(DynamicQueryObject query)
  49           {
  50               var  result =  this  .QueryService.Fetch(query);
  51  
 52               return   this  .NewtonsoftJson(result);
  53           }
  54       }
  55  }

万能查询对象

  1   using   System;
   2   using   System.Collections.Generic;
   3   using   System.Linq;
   4   using   System.Text;
   5   using   System.Threading.Tasks;
   6  
  7   namespace   Happy.Query
   8   {
   9       ///   <summary> 
 10       ///   动态查询对象。
  11       ///   </summary> 
 12       public   sealed   class   DynamicQueryObject
  13       {
  14           ///   <inheritdoc /> 
 15           public   DynamicQueryObject()
  16           {
  17               this .Columns =  new  List< string > ();
  18               this .Page =  1  ;
  19               this .ItemsPerPage =  25  ;
  20           }
  21  
 22           ///   <summary> 
 23           ///   表或试图名字。
  24           ///   </summary> 
 25           public   string  TableOrViewName {  get ;  set  ; }
  26  
 27           ///   <summary> 
 28           ///   表或试图名字。
  29           ///   </summary> 
 30           public  List< string > Columns {  get ;  set  ; }
  31  
 32           ///   <summary> 
 33           ///   Where子句。
  34           ///   </summary> 
 35           public   string  WhereClause {  get ;  set  ; }
  36  
 37           ///   <summary> 
 38           ///   Order子句。
  39           ///   </summary> 
 40           public   string  OrderClause {  get ;  set  ; }
  41  
 42           ///   <summary> 
 43           ///   第几页数据。
  44           ///   </summary> 
 45           public   long  Page {  get ;  set  ; }
  46  
 47           ///   <summary> 
 48           ///   每页条数。
  49           ///   </summary> 
 50           public   long  ItemsPerPage {  get ;  set  ; }
  51       }
  52  }

备注

写这篇文章的目的,是系统大家多给些意见,我想知道你们是如何应对这种查询需求的。

★快速评价★ : 不错,支持一下!  
★快速评价★ : 垃圾,还需努力!

 

分类:  CQRS ,  Happy Framework

作者: Leo_wl

    

出处: http://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于CQRS:CQRS+AJAX架构 之 查询(Q)模型设计的详细内容...

  阅读:51次