ServiceStack项目实例010ServiceStack.Northwind-2

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

创新互联公司主要从事做网站、成都网站设计、网页设计、企业做网站、公司建网站等业务。立足成都服务宽城,十年网站建设经验,价格优惠、服务专业,欢迎来电咨询建站服务:18980820575

    主要的服务文件 

    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();
            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.OrderByDescending(o => o.OrderDate))
                      .Skip((request.Page.GetValueOrDefault(1) - 1)*PageCount)
                      .Take(PageCount)
                      .ToList()
                : Db.Select(order => order.Where(o => o.CustomerId == request.CustomerId).OrderByDescending(o => o.CustomerId));
            if (orders.Count == 0)
                return new OrdersResponse();
                
            //根据订单获取订单详情信息,并据订单ID对订单详情数据进行分组
            var orderDetails = Db.Select(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.OrderByDescending(o => o.OrderDate))
                      .Skip((request.Page.GetValueOrDefault(1) - 1)*PageCount)
                      .Take(PageCount)
                      .ToList()
                : Db.Select(order => order.Where(o => o.CustomerId == request.CustomerId).OrderByDescending(o => o.CustomerId));

       

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

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

     其中

orders.ConvertAll(x => x.Id)

     的内容如下:

     ServiceStack 项目实例 010 ServiceStack.Northwind - 2

     

     这个表达式

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);

      跟踪的结构如下图:

      ServiceStack 项目实例 010 ServiceStack.Northwind - 2     可以看到根据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()
            });

      跟踪的结果如下:

      ServiceStack 项目实例 010 ServiceStack.Northwind - 2

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

    

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


当前名称:ServiceStack项目实例010ServiceStack.Northwind-2
本文地址:http://ybzwz.com/article/jidish.html