天天看点

Dot Net FrameWork 4.0 学习笔记(6)

 不得不在这里吐槽一下,年终总结的高难度,高挑战性,历时三天我也没能想出个所以然,道是把学习笔记完工了,情何以堪      

    ADO.NET Data Services 1.5(WCF Data Services) 的新增功能

    1,支持服务端的 RowCount - 获取指定实体集合的成员数(只返回一个整型值,而不会返回实体集合)  

    2,支持服务端的分页 - 服务端可以返回分页后的数据,并且在其中还可以包含全部数据总数  

    3,支持服务端的 Select - 返回的结果只包括 Select 的字段  

    4,支持大数据传输 BLOB(binary large object)

    5,支持自定义数据服务

    1. RowCount (当然新玩意就要配置点新协议了 config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;)

    rowCount只有在数据服务协议第二版本才能使用

    $count - 返回 RowCount,即对应集合的成员数(只返回一个整型值,而不会返回实体集合)

    http://localhost:12345/WcfDataService1.svc/EmployeeInfo/$count

    $inlinecount=none - 只返回实体集合(分页后的数据)

    http://localhost:12345/WcfDataService1.svc/EmployeeInfo/$inlinecount=none

    $inlinecount=allpages - 在返回实体集合的基础上(分页后的数据),其中还会包括一个实体集合成员数(分页前的数据)的字段

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

    2. 数据服务分页

    // 设置服务器分页方式

    config.SetEntitySetPageSize("EmployeeInfo", 5);

    // 客户端则使用 

    http://localhost:12345/WcfDataService1.svc/EmployeeInfo?$skip=10

    // 当然可以使用rowcount中的$inlinecount来获取数据

    3. select字段及多参数

    $select=[column1,column2,column3,...] - 返回的实体集合数据中只包括指定的字段

    http://localhost:12345/WcfDataService1.svc/EmployeeInfo/?$select=EmployeeId,EmployeeName/&$inlinecount=allpages

    4. BLOB大数据对象

    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.Data.Services.Providers 此命名空间之下

    public class WcfDataService1 : DataService<HrmsDBEntities>,IServiceProvider

    {

        // 仅调用此方法一次以初始化涉及服务范围的策略。

        public static void InitializeService(DataServiceConfiguration config)

        {

            config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;

            // 设置规则以指明哪些实体集和服务操作是可见的、可更新的,等等。

            // config.SetEntitySetAccessRule("MyEntityset", EntitySetRights.AllRead);  // 设置访问范围

            // config.SetServiceOperationAccessRule("MyServiceOperation", ServiceOperationRights.All);  // 设置服务谓词访问

            config.SetEntitySetAccessRule("EmployeeInfo", EntitySetRights.AllRead | EntitySetRights.AllWrite);

        }

        public object GetService(Type serviceType)

            if (serviceType != typeof(IDataServiceStreamProvider))

            {

                return null;

            }

            // 调用服务的时候,如果指定了需要流式传输大数据对象,则通过我们自定义的流式文件传输对象去处理

            return new StreamProvider();

    }

    // 数据服务流提供实现类,需要实现IDataServiceStreamProvider接口

    public class StreamProvider : IDataServiceStreamProvider

        public void DeleteStream(object entity, System.Data.Services.DataServiceOperationContext operationContext)

            throw new NotImplementedException();

        // 返回流

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

            if (entity as EmployeeInfo == null)

            string employeeId = (entity as EmployeeInfo).EmployeeId;

            using (var context = new HrmsDBEntities())

                var employee = context.EmployeeInfo.First(p => p.EmployeeId == employeeId);

                var stream = new MemoryStream(byte.Parse(employee.EmployeePicture));

                return stream;

        public Uri GetReadStreamUri(object entity, System.Data.Services.DataServiceOperationContext operationContext)

            return null;

        // 返回内容

        public string GetStreamContentType(object entity, System.Data.Services.DataServiceOperationContext operationContext)

            return "image/jpeg";

        public string GetStreamETag(object entity, System.Data.Services.DataServiceOperationContext operationContext)

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

        public string ResolveType(string entitySetName, System.Data.Services.DataServiceOperationContext operationContext)

        // 流缓冲大小

        public int StreamBufferSize

            get { return 64; }

    // 获取EmployeeInfo表上主键为zx0000000007的值

    调用获取 http://localhost:12345/WcfDataService1.svc/EmployeeInfo(zx0000000007)/$value

    5. 自定义数据服务呢,就是将EF的实现过程我们手写一遍啦

    要注意将数据上下文对象实现IQueryable接口,DataServiceKeyAttribute() 指定主键字段

    EntityPropertyMapping() 实体属性到 ATOM 字段(可以理解为外键字段)的映射,以便生成一个友好格式的 Feed

    // 设置规则以指明哪些实体集和服务操作是可见的、可更新的,等等。

    // config.SetEntitySetAccessRule("MyEntityset", EntitySetRights.AllRead);  // 设置访问范围

    // config.SetServiceOperationAccessRule("MyServiceOperation", ServiceOperationRights.All);  // 设置服务谓词访问

    config.SetEntitySetAccessRule("EmployeeInfo", EntitySetRights.AllRead | EntitySetRights.AllWrite); 

    ps:就如开头说的,如何将CLR类型数据转换成具有平台互操互性数据,我们可以利用WCF DataService

    WCF DataService巧妙利用了REST架构来实现对资源的访问,也利用自身SOAP特点将数据完美展现

    到此为止我们的4.0新特性归结到此,其实4.0的东西远不止这些,这些只是一些常用的...

    补记: 摘自MSDN

    // 自定义数据展示

    using System;

  using System.Collections.Generic;  using System.Data.Services;  using System.Data.Services.Common;  using System.Linq;  namespace CustomDataServiceClient  {    [DataServiceKeyAttribute("OrderId")]    public class Order    {        public int OrderId { get; set; }        public string Customer { get; set; }        public IList<Item> Items { get; set; }    }    [DataServiceKeyAttribute("Product")]    public class Item    {        public string Product { get; set; }        public int Quantity { get; set; }    }    public partial class OrderItemData    {        static IList<Order> _orders;        static IList<Item> _items;        static OrderItemData()        {            _orders = new Order[]{              new Order(){ OrderId=0, Customer = "Peter Franken", Items = new List<Item>()},              new Order(){ OrderId=1, Customer = "Ana Trujillo", Items = new List<Item>()}};            _items = new Item[]{              new Item(){ Product="Chai", Quantity=10 },              new Item(){ Product="Chang", Quantity=25 },              new Item(){ Product="Aniseed Syrup", Quantity = 5 },              new Item(){ Product="Chef Anton's Cajun Seasoning", Quantity=30}};            _orders[0].Items.Add(_items[0]);            _orders[0].Items.Add(_items[1]);            _orders[1].Items.Add(_items[2]);            _orders[1].Items.Add(_items[3]);        }        public IQueryable<Order> Orders        {            get { return _orders.AsQueryable<Order>(); }        }        public IQueryable<Item> Items        {            get { return _items.AsQueryable<Item>(); }        }    }    public class OrderItems : DataService<OrderItemData>    {        public static void InitializeService(IDataServiceConfiguration                                             config)        {            config.SetEntitySetAccessRule("Orders", EntitySetRights.All);            config.SetEntitySetAccessRule("Items", EntitySetRights.All);        }    }  }    

  // LINQ TO SQL实体  using System;  using System.ComponentModel;  using System.Collections;  using System.Linq;  using System.Reflection;  using System.Data.Linq;  using System.Data.Linq.Mapping;  using System.Data.Services;  using System.Data.Services.Common;  namespace NorthwindService  {    // Define the key properties for the LINQ to SQL data classes.    [DataServiceKeyAttribute("CustomerID")]    public partial class Customer { }    [DataServiceKeyAttribute("ProductID")]    public partial class Product { }    [DataServiceKeyAttribute("OrderID")]    public partial class Order { }    [DataServiceKeyAttribute("OrderID", "ProductID")]    public partial class Order_Detail { }    // Define the IUpdatable implementation for LINQ to SQL.    public partial class NorthwindDataContext : IUpdatable    {        // Creates an object in the container.        object IUpdatable.CreateResource(string containerName, string fullTypeName)        {            Type t = Type.GetType(fullTypeName, true);            ITable table = GetTable(t);            object resource = Activator.CreateInstance(t);            table.InsertOnSubmit(resource);            return resource;        }        // Gets the object referenced by the resource.        object IUpdatable.GetResource(IQueryable query, string fullTypeName)        {            object resource = query.Cast<object>().SingleOrDefault();            // fullTypeName can be null for deletes            if (fullTypeName != null && resource.GetType().FullName != fullTypeName)                throw new ApplicationException("Unexpected type for this resource.");            return resource;        }        // Resets the value of the object to its default value.        object IUpdatable.ResetResource(object resource)        {            Type t = resource.GetType();            MetaTable table = Mapping.GetTable(t);            object dummyResource = Activator.CreateInstance(t);            foreach (var member in table.RowType.DataMembers)            {                if (!member.IsPrimaryKey && !member.IsDeferred &&                    !member.IsAssociation && !member.IsDbGenerated)                {                    object defaultValue = member.MemberAccessor.GetBoxedValue(dummyResource);                    member.MemberAccessor.SetBoxedValue(ref resource, defaultValue);                }            }            return resource;        }        // Sets the value of the given property on the object.        void IUpdatable.SetValue(object targetResource, string propertyName, object propertyValue)        {            MetaTable table = Mapping.GetTable(targetResource.GetType());            MetaDataMember member = table.RowType.DataMembers.Single(x => x.Name == propertyName);            member.MemberAccessor.SetBoxedValue(ref targetResource, propertyValue);        }        // Gets the value of a property on an object.        object IUpdatable.GetValue(object targetResource, string propertyName)        {            MetaTable table = Mapping.GetTable(targetResource.GetType());            MetaDataMember member =                table.RowType.DataMembers.Single(x => x.Name == propertyName);            return member.MemberAccessor.GetBoxedValue(targetResource);        }        // Sets the related object for a reference.        void IUpdatable.SetReference(            object targetResource, string propertyName, object propertyValue)        {            ((IUpdatable)this).SetValue(targetResource, propertyName, propertyValue);        }        // Adds the object to the related objects collection.        void IUpdatable.AddReferenceToCollection(            object targetResource, string propertyName, object resourceToBeAdded)        {            PropertyInfo pi = targetResource.GetType().GetProperty(propertyName);            if (pi == null)                throw new Exception("Can't find property");            IList collection = (IList)pi.GetValue(targetResource, null);            collection.Add(resourceToBeAdded);        }        // Removes the object from the related objects collection.        void IUpdatable.RemoveReferenceFromCollection(            object targetResource, string propertyName, object resourceToBeRemoved)        {            PropertyInfo pi = targetResource.GetType().GetProperty(propertyName);            if (pi == null)                throw new Exception("Can't find property");            IList collection = (IList)pi.GetValue(targetResource, null);            collection.Remove(resourceToBeRemoved);        }        // Deletes the resource.        void IUpdatable.DeleteResource(object targetResource)        {            ITable table = GetTable(targetResource.GetType());            table.DeleteOnSubmit(targetResource);        }        // Saves all the pending changes.        void IUpdatable.SaveChanges()        {            SubmitChanges();        }        // Returns the actual instance of the resource represented         // by the resource object.        object IUpdatable.ResolveResource(object resource)        {            return resource;        }        // Reverts all the pending changes.        void IUpdatable.ClearChanges()        {            // Raise an exception as there is no real way to do this with LINQ to SQL.            // Comment out the following line if you'd prefer a silent failure            throw new NotSupportedException();        }    }}  

     本文转自My_King1 51CTO博客,原文链接:http://blog.51cto.com/apprentice/1360547,如需转载请自行联系原作者