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

本文深入探讨了CQRS架构在处理复杂查询需求时的实践与思考,包括查询面板、高级查询、权限控制等场景。文章重点阐述了如何通过SQL和动态类型优势进行设计,以及关键决策如直接查询数据库、利用策略防止SQL注入和权限提升。通过示例代码展示了动态查询控制器和查询对象的实现,旨在提供一种高效灵活的查询解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原帖地址:http://www.cnblogs.com/happyframework/archive/2013/05/23/3094164.html

背景


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


真心的系统大家看完给出你们的意见和想法。

什么是CQRS


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

简单的CQRS



复杂的CQRS



CQRS的常见查询需求


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


查询面板



高级查询



数据行级别的权限


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


固定约束


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


需求总结



CQRS的查询设计


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

关键决策:




    1. 直接查询数据库返回Dynamic类型,不需要定义强类型。
    2. 直接用SQL,支持动态查询面板和动态数据行权限。目前没有找到封装SQL的理由,最多是在外围再封装一层,但是不会隐藏SQL(我之前写过一个简单的查询对象)。
    3. 利用一些策略防止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 }


备注


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


 

本文链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值