ServiceStack.Northwind这个项目中提供了三表关联操作和缓存方式操作数据的示例。

主要的服务文件

CustomersService.cs :查询客户列表

OrdersService.cs :  查询一组订单以及和该组订单相关的订单项,其中每个订单包含客户信息和具体商品详情,共涉及到三个表。

CustomerDetailsService.cs 一个客户及其订单,被前一个服务(OrdersService)调用。

CachedServices.cs 使用缓存方式,对上面三个服务进行封装,缓存使用的MemoryCacheClient。

ServiceStack的缓存支持多种形式存储,包括Memory,Redis,MemoryCached,SQLAlchemy等,但是仅用于缓存自身的服务,并不是通用功能的缓存,所以使用范围很有限。

CustomersService.cs的代码,获取所有用户的列表,这个功能很简单,不加说明了。

        public CustomersResponse Get(Customers request){var customers = Db.Select<Customer>();return new CustomersResponse { Customers = customers };}

OrdersService.cs 的代码,用来获取多组订单信息,注意是多组,使用了.net集合处理的一些功能。这个服务先获取一组或一个订单,再根据订单获取订单详情信息,获取订单详情的时候根据订单ID对订单详情数据进行分组。

public class OrdersService : ServiceStack.ServiceInterface.Service{//指定分页式每页几条记录private const int PageCount = 8;public object Get(Orders request){//获取一组或一个订单var orders = request.CustomerId.IsNullOrEmpty()? Db.Select<Order>(order => order.OrderByDescending(o => o.OrderDate)).Skip((request.Page.GetValueOrDefault(1) - 1)*PageCount).Take(PageCount).ToList(): Db.Select<Order>(order => order.Where(o => o.CustomerId == request.CustomerId).OrderByDescending(o => o.CustomerId));if (orders.Count == 0)return new OrdersResponse();//根据订单获取订单详情信息,并据订单ID对订单详情数据进行分组var orderDetails = Db.Select<OrderDetail>(detail => Sql.In(detail.OrderId, orders.ConvertAll(x => x.Id)));var orderDetailsLookup = orderDetails.ToLookup(o => o.OrderId);var customerOrders = orders.ConvertAll(o => new CustomerOrder {Order = o,OrderDetails = orderDetailsLookup[o.Id].ToList()});return new OrdersResponse { Results = customerOrders };}}

分步说明:1 订单列表

获取订单信息,判断传入的 CustomerId 是否为空,如果CustomerId为空,执行分页方式查询订单的列表,分页的语法和EF中是相同的;如果有CustomerId,就会执行获取一条订单的操作。

var orders = request.CustomerId.IsNullOrEmpty()? Db.Select<Order>(order => order.OrderByDescending(o => o.OrderDate)).Skip((request.Page.GetValueOrDefault(1) - 1)*PageCount).Take(PageCount).ToList(): Db.Select<Order>(order => order.Where(o => o.CustomerId == request.CustomerId).OrderByDescending(o => o.CustomerId));

根据获取的OrderId的列表,获取订单详情列表。

var orderDetails = Db.Select<OrderDetail>(detail => Sql.In(detail.OrderId, orders.ConvertAll(x => x.Id)));

其中

orders.ConvertAll(x => x.Id)

的内容如下:

这个表达式

detail => Sql.In(detail.OrderId, orders.ConvertAll(x => x.Id))

实现的效果和SQL中的In子句对应,不过传入的参数有一点差异,第一个参数detail.OrderId指定字段名,第二个参数需要是一个×××值ID的列表,如上图跟踪时的oid的结构。

分步说明:2 分组的订单详情列表

       在这个示例中 orderDetails 变量查询后获得了44项数据。下一步根据OrderId对获得的这44项数据进行分组。

       var orderDetailsLookup = orderDetails.ToLookup(o => o.OrderId);

跟踪的结构如下图:

    可以看到根据8个OrderId, 将44个订单详情数据分组成8组,并且是可以根据OrderId为索引,获取其中某一组的信息(在下一步我们可以看到这个过程)。

(ToLookup是.net集合中内置的一个函数,对集合中数据根据某一个字段进行分组)

分步说明:3 将订单列表和分组的详情列表组合

现在我们获得了8个订单项,还有44个根据订单的ID分组好的详情列表,下面我们把每一条订单的数据和对应的订单详情组合起来。

通过ConvertAll函数,逐项添加CustomerOrder,每个CustomerOrder包含有一个订单数据,和一组和该项订单相关的订单详情项。

var customerOrders = orders.ConvertAll(o => new CustomerOrder {Order = o,OrderDetails = orderDetailsLookup[o.Id].ToList()});

跟踪的结果如下:

有8个订单项,每个订单包含有数量不等的订单详情项。也就是一个订单记录对应了多个购买的商品。

源代码下载: http://down.51cto.com/data/1976805

转载于:https://blog.51cto.com/soaop/1595191

ServiceStack 项目实例 010 ServiceStack.Northwind - 2相关推荐

  1. ServiceStack 项目实例 001 建立项目结构

    ServiceStack 用于服务开发,可以为各种形式的网站.软件.APP等提供数据服务,可以提供REST,WebService以及二级制数据形式的服务. 下面根据我们具体项目要求,说一下建立项目的方 ...

  2. 使用 ServiceStack 构建跨平台 Web 服务(转)

    出处:http://www.cnblogs.com/shanyou/p/3348347.html 本文主要来自MSDN杂志<Building Cross-Platform Web Service ...

  3. 使用 ServiceStack 构建跨平台 Web 服务

    本文主要来自MSDN杂志<Building Cross-Platform Web Services with ServiceStack>,Windows Communication Fou ...

  4. Redis在C#中的使用及Redis的封装

    Redis是一款开源的.高性能的键-值存储(key-value store).它常被称作是一款数据结构服务器(data structure server).Redis的键值可以包括字符串(string ...

  5. 使用ServiceStackRedis链接Redis简介

     注:关于如何在windows,linux下配置redis,详见这篇文章:) 目前网上有一些链接Redis的C#客户端工具,这里介绍其中也是目前我们企业版产品中所使用的ServiceStackRedi ...

  6. Redis总结(二)C#中如何使用redis

    上一篇讲述了安装redis<Redis总结(一)Redis安装>,同时也大致介绍了redis的优势和应用场景.本篇着重讲解.NET中如何使用redis和C#. Redis官网提供了很多开源 ...

  7. ASP.NET Redis 开发

    Redis简介 Redis是一个开源的,使用C语言编写,面向"键/值"对类型数据的分布式NoSQL数据库系统,特点是高性能,持久存储,适应高并发的应用场景.Redis纯粹为应用而产 ...

  8. Redis_简单使用

    可基于内存也可持久化的Key-Value(字典, Remote Dictionary Server,远程字典服务器)数据库. 客户端:http://redis.io/clients 命令:http:/ ...

  9. Redis调用及使用

    首先第一步: 添加引用 1.ServiceStack.DLL ServiceStack.Interfaces.DLL ServiceStack.ServiceInterface.DLL 以上引用都可以 ...

最新文章

  1. Python培训教程分享:Python异常机制
  2. Struts访问web元素
  3. feign服务器响应数据量过大,SpringCloud之Feign 性能优化
  4. 聊一聊SpringCloudNetflix的五大组件(神兽)
  5. jQuery 源码系列(四)Tokens 词法分析
  6. redis学习-列表(list)常用命令
  7. spinlock导读
  8. DevExpress学习笔记之如何获取Repository Item的值
  9. 微软 .NET Core 3.0 版本发布
  10. 动态开辟内存_C/C++工程师你理解程序的内存分区吗?
  11. 手写数学公式自动识别工具、表格自动识别
  12. 2021智能仓储物流之最全AGV企业供应商名录整理分享~
  13. 思古解析js静态逆向分析
  14. 使用google翻译免费翻译文档,这里以pdf为例
  15. angular路由守卫
  16. 测试-- 自动化测试selenium(关于API)
  17. 2016苹果开发者账号注册申请流程链接
  18. RocketMQ Web控制台监控界面介绍+部署
  19. matlab插值与拟合(命令与示例),matlab插值与拟合(命令与示例)
  20. C语言,十进制转化为二进制。

热门文章

  1. .Net下的XML序列化(一)
  2. Control Web Panel 中两个严重漏洞使Linux 服务器易受RCE攻击
  3. WebLogic UniversalExtractor反序列化漏洞(CVE-2020-14645)的复现和分析
  4. Citrix SD-WAN 被曝远程代码执行漏洞
  5. LG 源代码或被盗,如何才能毫发无损地要回来?
  6. 签约!睿铂与泰瑞数创共同助力实景三维中国建设
  7. 套接字socket 的地址族和类型、工作原理、创建过程
  8. 在Linux中查找用户帐户信息和登录详细信息的11种方法
  9. JavaScript实现继承的方式
  10. Linux 内核的测试和调试(1)