天天看點

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,如需轉載請自行聯系原作者