天天看點

精進不休 .NET 4.0 (6) - ADO.NET Data Services 1.5 新特性

[索引頁]

[×××]

精進不休 .NET 4.0 (6) - ADO.NET Data Services 1.5 新特性

作者:webabcd

介紹

ADO.NET Data Services 1.5 的新增功能

  • 支援服務端的 RowCount - 擷取指定實體集合的成員數(隻傳回一個整型值,而不會傳回實體集合) 
  • 支援服務端的分頁 - 服務端可以傳回分頁後的資料,并且在其中還可以包含全部資料總數 
  • 支援服務端的 Select - 傳回的結果隻包括 Select 的字段 
  • 支援大資料傳輸 BLOB(binary large object)
  • 支援自定義資料服務 

示例

1、服務端 RowCount 的 Demo

MyDataService.svc.cs

using System;

using System.Collections.Generic;

using System.Data.Services;

using System.Data.Services.Common;

using System.Linq;

using System.ServiceModel.Web;

using System.Web;

namespace DataAccess.DataServices.Service

{

        [System.ServiceModel.ServiceBehavior(IncludeExceptionDetailInFaults = true)]

        public class MyDataService : DataService<MyEntity.AdventureWorksEntities>

        {

static void InitializeService() static void InitializeService(DataServiceConfiguration config)

                {

                        config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;

                        config.SetEntitySetAccessRule("Products", EntitySetRights.All);

                        // SetEntitySetPageSize(string name, int size) - 新增的方法。用于提供分頁後的資料

                        //         string name - 指定需要用于分頁的實體集合

                        //         int size - 分頁的頁大小

                        config.SetEntitySetPageSize("Products", 5);

                }

        }

}

RowCount.aspx.cs

using System.Web.UI;

using System.Web.UI.WebControls;

namespace DataAccess.DataServices

        public partial class RowCount : System.Web.UI.Page

void Page_Load() void Page_Load(object sender, EventArgs e)

                        MyDataServiceProxy.AdventureWorksEntities context = new MyDataServiceProxy.AdventureWorksEntities(new Uri("http://localhost:9046/DataServices/Service/MyDataService.svc/"));

                        // 支援服務端的 RowCount - 擷取指定實體集合的成員數(隻傳回一個整型值,而不會傳回實體集合)

                        var productCount = context.Products.Count();

                        Response.Write(productCount.ToString());

}

/*

$count - 傳回 RowCount,即對應集合的成員數(隻傳回一個整型值,而不會傳回實體集合)

http://localhost:9046/DataServices/Service/MyDataService.svc/Products/$count

$inlinecount=none - 隻傳回實體集合(分頁後的資料)

http://localhost:9046/DataServices/Service/MyDataService.svc/Products?$inlinecount=none

$inlinecount=allpages - 在傳回實體集合的基礎上(分頁後的資料),其中還會包括一個實體集合成員數(分頁前的資料)的字段

http://localhost:9046/DataServices/Service/MyDataService.svc/Products?$inlinecount=allpages

*/

2、服務端分頁的 Demo

MyDataService.svc.cs

Paging.aspx.cs

        public partial class Paging : System.Web.UI.Page

                        // 支援服務端的分頁 - 服務端可以傳回分頁後的資料,并且在其中還可以包含全部資料總數

                        //         服務端代碼:config.SetEntitySetPageSize("Products", 5); 表示每頁最多 5 條資料

                        //         用戶端代碼:通過 Skip() 方法來控制需要跳過的記錄數

                        var products = context.Products.Skip(10);

                        foreach (var product in products)

                        {

                                Response.Write(product.ProductID.ToString() + "<br />");

                        }

$skip=[int] - 指定需要跳過的記錄數

http://localhost:9046/DataServices/Service/MyDataService.svc/Products?$skip=10

3、服務端 Select 的 Demo

QueryProjection.aspx.cs

        public partial class QueryProjection : System.Web.UI.Page

                        // 支援服務端的 Select - 傳回的結果隻包括 Select 的字段

                        var products = context.Products.Select(p => new { ProductID = p.ProductID, Name = p.Name });

                                Response.Write(product.ProductID.ToString() + ": " + product.Name + "<br />");

$select=[column1,column2,column3,...] - 傳回的實體集合資料中隻包括指定的字段

http://localhost:9046/DataServices/Service/MyDataService.svc/Products/?$select=ProductID,Name

4、BLOB 的 Demo

BLOBService.svc.cs

ADO.NET Data Services 1.5 - 新增了對大資料傳輸 BLOB(binary large object)的支援

需要在概念模型(ConceptualModels)中的相關實體上增加屬性“m:HasStream="true" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"”

*/

using System.IO;

        public class BLOBService : DataService<MyEntity.AdventureWorksEntities>, IServiceProvider

object GetService() object GetService(Type serviceType)

                        if (serviceType != typeof(System.Data.Services.Providers.IDataServiceStreamProvider))

                                return null;

                        // 調用服務的時候,如果指定了需要流式傳輸大資料對象,則通過我們自定義的流式檔案傳輸對象去處理

                        return new ProductPhotoStreamProvider();

        /// <summary>

        /// 自定義的一個流式檔案傳輸類,需要實作 System.Data.Services.Providers.IDataServiceStreamProvider 接口

        /// </summary>

        public class ProductPhotoStreamProvider : System.Data.Services.Providers.IDataServiceStreamProvider

                /// <summary>

                /// 擷取流。将某個實體的某個屬性以流類型的方式傳回

                /// </summary>

                /// <param name="entity">相關的實體</param>

                /// <param name="operationContext">目前資料服務請求的上下文</param>

                /// <returns></returns>

Stream GetReadStream() Stream GetReadStream(object entity, string etag, bool? checkETagForEquality, DataServiceOperationContext operationContext)

                        if (entity as MyEntity.Product == null)

                        int productId = (entity as MyEntity.Product).ProductID;

                        using (var context = new MyEntity.AdventureWorksEntities())

                                var product = context.Products.First(p => p.ProductID == productId);

                                var stream = new MemoryStream(product.ThumbNailPhoto);

                                return stream;

Uri GetReadStreamUri() Uri GetReadStreamUri(object entity, DataServiceOperationContext operationContext)

                        return null;

                // 流的内容類型

string GetStreamContentType() string GetStreamContentType(object entity, DataServiceOperationContext operationContext)

                        return "p_w_picpath/jpeg";

string GetStreamETag() string GetStreamETag(object entity, DataServiceOperationContext operationContext)

                // 流的緩沖區大小

                public int StreamBufferSize

                        get { return 64; }

void DeleteStream() void DeleteStream(object entity, DataServiceOperationContext operationContext)

                        throw new NotImplementedException();

System.IO.Stream GetWriteStream() System.IO.Stream GetWriteStream(object entity, string etag, bool? checkETagForEquality, DataServiceOperationContext operationContext)

string ResolveType() string ResolveType(string entitySetName, DataServiceOperationContext operationContext)

BLOB.aspx

<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true"

        CodeBehind="BLOB.aspx.cs" Inherits="DataAccess.DataServices.BLOB" %>

<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">

</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">

        <!--

                檢視中繼資料 - http://localhost:9046/DataServices/Service/BLOBService.svc/$metadata

        -->

                Products(714) - 在 Products 集合中取主鍵為 714 的實體

                $value - 取流資料

        <img src="http://localhost:9046/DataServices/Service/BLOBService.svc/Products(714)/$value" alt="p_w_picpath" />

</asp:Content>

5、自定義資料服務的 Demo

CustomDataService.svc.cs

ADO.NET Data Services 1.5 - 新增了對自定義資料服務的支援    

        public class CustomDataService : DataService<OrderContext>

                        config.SetEntitySetAccessRule("Orders", EntitySetRights.All);

        /// 資料上下文

        public class OrderContext

                static List<Order> _orders;

                static List<Product> _products;

                static OrderContext()

                        _orders = new List<Order>

                                new Order { OrderId = 0, Customer="webabcd"},

                                new Order { OrderId = 1, Customer="webabcdefg"}

                        };

                        _products = new List<Product>

                                new Product { ProductId = 0, ProductName="wii", Price=100 },    

                                new Product { ProductId = 1, ProductName="xbox360", Price=200 },    

                                new Product { ProductId = 2, ProductName="ps3", Price = 300 },    

                                new Product { ProductId = 3, ProductName="nds", Price=50 },

                                new Product { ProductId = 4, ProductName="psp", Price=100 }

                        _orders[0].Items.Add(_products[0]);

                        _orders[0].Items.Add(_products[1]);

                        _orders[1].Items.Add(_products[2]);

                        _orders[1].Items.Add(_products[3]);

                        _orders[1].Items.Add(_products[4]);

                public IQueryable<Order> Orders

                        get { return _orders.AsQueryable<Order>(); }

                public IQueryable<Product> Products

                        get { return _products.AsQueryable<Product>(); }

        /*

         * DataServiceKeyAttribute() - 指定主鍵字段

         * EntityPropertyMapping() - 實體屬性到 ATOM 字段的映射,以便生成一個友好格式的 Feed    

         */

        [EntityPropertyMapping("Customer", SyndicationItemProperty.AuthorName, SyndicationTextContentKind.Plaintext, true)]

        [DataServiceKeyAttribute("OrderId")]

        public class Order

                public int OrderId { get; set; }

                public string Customer { get; set; }

                private List<Product> _items;

                public List<Product> Items

                        get

                                if (_items == null)

                                        _items = new List<Product>();

                                return _items;

                        set

                                _items = value;

        [DataServiceKeyAttribute("ProductId")]

        public class Product

                public int ProductId { get; set; }

                public string ProductName { get; set; }

                public int Price { get; set; }

CustomDataService.aspx.cs

        public partial class CustomDataService : System.Web.UI.Page

                        // 使用自定義資料服務提供的服務

                        CustomDataServiceProxy.OrderContext context = new CustomDataServiceProxy.OrderContext(new Uri("http://localhost:9046/DataServices/Service/CustomDataService.svc/"));

                        var orders = context.Orders;

                        foreach (var order in orders)

                                Response.Write(order.OrderId.ToString() + "<br />");

注:

以 URI 文法的方式查詢 ADO.NET 資料服務的形式如下:

http://[Url]/[ServiceName]/[EntityName]/[NavigationOptions]?[QueryOptions]

詳細文法參看 MSDN

OK

[×××]

繼續閱讀