精进不休 .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; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
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
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); 
                } 
        } 
}
 
Paging.aspx.cs
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Web.UI; 
using System.Web.UI.WebControls; 

namespace DataAccess.DataServices 

        public partial class Paging : 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/")); 

                        // 支持服务端的分页 - 服务端可以返回分页后的数据,并且在其中还可以包含全部数据总数 
                        //         服务端代码: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 

$inlinecount=none - 只返回实体集合(分页后的数据) 
http://localhost:9046/DataServices/Service/MyDataService.svc/Products?$inlinecount=none 

$inlinecount=allpages - 在返回实体集合的基础上(分页后的数据),其中还会包括一个实体集合成员数(分页前的数据)的字段 
http://localhost:9046/DataServices/Service/MyDataService.svc/Products?$inlinecount=allpages 
*/
 
 
3、服务端 Select 的 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); 
                } 
        } 
}
 
QueryProjection.aspx.cs
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Web.UI; 
using System.Web.UI.WebControls; 

namespace DataAccess.DataServices 

        public partial class QueryProjection : 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/")); 

                        // 支持服务端的 Select - 返回的结果只包括 Select 的字段 
                        var products = context.Products.Select(p => new { ProductID = p.ProductID, Name = p.Name }); 

                        foreach (var product in products) 
                        { 
                                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; 
using System.Collections.Generic; 
using System.Data.Services; 
using System.Data.Services.Common; 
using System.Linq; 
using System.ServiceModel.Web; 
using System.Web; 

using System.IO; 

namespace DataAccess.DataServices.Service 

        [System.ServiceModel.ServiceBehavior(IncludeExceptionDetailInFaults = true)] 
        public class BLOBService : DataService<MyEntity.AdventureWorksEntities>, IServiceProvider 
        { 
static void InitializeService() static void InitializeService(DataServiceConfiguration config) 
                { 
                        config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2; 
                        config.SetEntitySetAccessRule("Products", EntitySetRights.All); 
                } 

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
                                return 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 "image/jpeg"
                } 

string GetStreamETag() string GetStreamETag(object entity, DataServiceOperationContext operationContext) 
                { 
                        return null
                } 

                // 流的缓冲区大小 
                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) 
                { 
                        throw new NotImplementedException(); 
                } 

string ResolveType() string ResolveType(string entitySetName, DataServiceOperationContext operationContext) 
                { 
                        throw new NotImplementedException(); 
                } 
        } 
}
 
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="image" /> 

</asp:Content>
 
 
5、自定义数据服务的 Demo
CustomDataService.svc.cs
/* 
ADO.NET Data Services 1.5 - 新增了对自定义数据服务的支持    
*/ 

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 CustomDataService : DataService<OrderContext> 
        { 
static void InitializeService() static void InitializeService(DataServiceConfiguration config) 
                { 
                        config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2; 
                        config.SetEntitySetAccessRule("Orders", EntitySetRights.All); 
                        config.SetEntitySetAccessRule("Products", EntitySetRights.All); 
                } 
        } 

        /// <summary> 
        /// 数据上下文 
        /// </summary> 
        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 { getset; } 
                public string Customer { getset; } 

                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 { getset; } 
                public string ProductName { getset; } 
                public int Price { getset; } 
        } 
}
 
CustomDataService.aspx.cs
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Web.UI; 
using System.Web.UI.WebControls; 

namespace DataAccess.DataServices 

        public partial class CustomDataService : System.Web.UI.Page 
        { 
void Page_Load() void Page_Load(object sender, EventArgs e) 
                { 
                        // 使用自定义数据服务提供的服务 
                        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 
[源码下载]
 
 




     本文转自webabcd 51CTO博客,原文链接:http://blog.51cto.com/webabcd/341317,如需转载请自行联系原作者
上一篇:Jmeter接口测试


下一篇:[JQuery]用InsertAfter实现图片走马灯展示效果