您好,登錄后才能下訂單哦!
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
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。