天天看点

精进不休 .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

[×××]

继续阅读