自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

使用LINQ和ADO.NET創(chuàng)建Silverlight程序

原創(chuàng)
開(kāi)發(fā) 后端
以數(shù)據(jù)為中心的Web應(yīng)用程序變得越來(lái)越重要,使用Silverlight 2、LINQ和ADO.NET很容易創(chuàng)建富的、以數(shù)據(jù)為驅(qū)動(dòng)的Web應(yīng)用程序,本文向你展示創(chuàng)建Silverlight應(yīng)用程序的基礎(chǔ)知識(shí),如果將其連接到數(shù)據(jù)源后你的程序會(huì)變得更加閃亮。

51CTO.com獨(dú)家特稿】在Silverlight中可以創(chuàng)建行業(yè)和其它以數(shù)據(jù)為中心的應(yīng)用系統(tǒng),但在Silverlight中處理數(shù)據(jù)不是一件容易的事情,由于Silverlight包括許多處理數(shù)據(jù)和支持Web Service及XML的工具,但這些工具僅代表跨過(guò)防火墻進(jìn)行數(shù)據(jù)訪問(wèn)的最基礎(chǔ)的部分。

常見(jiàn)的數(shù)據(jù)訪問(wèn)策略是使用Web Service和客戶端LINQ共同實(shí)現(xiàn)的,如果你正在修改現(xiàn)有Web Service端點(diǎn)強(qiáng)化你的Silverlight應(yīng)用程序,那么我推薦你使用這個(gè)方法。但如果你在使用Silverlight創(chuàng)建一個(gè)新的Web Service,就沒(méi)有必要這么做了。

對(duì)一個(gè)典型的Web Service層而言,你在服務(wù)器上實(shí)現(xiàn)一個(gè)傳統(tǒng)的數(shù)據(jù)訪問(wèn)策略(自定義業(yè)務(wù)對(duì)象、LINQ to SQL、實(shí)體框架、Nhibernate等)通過(guò)Web Service暴露數(shù)據(jù)對(duì)象,Web Service僅僅是數(shù)據(jù)訪問(wèn)策略下面的網(wǎng)關(guān)。

但為了開(kāi)啟完整的數(shù)據(jù)連通性,你必須要映射四個(gè)數(shù)據(jù)操作(創(chuàng)建、讀取、更新和刪除)到Web Service方法,下面是一個(gè)簡(jiǎn)單的支持Product類的service contract,注意我在本文中使用的都是C#。

例1 Product Web Service的Service Contract

[ServiceContract]
public interface ICustomerService
{
  [OperationContract]
  List GetAllProducts();
  [OperationContract]
  Product GetProduct(int productID);
  [OperationContract]
  List GetAllProductsWithCategories();
  [OperationContract]
  Product SaveProduct(Product productToSave);
  [OperationContract]
  void DeleteProduct(Product productToDelete);
}

創(chuàng)建一套服務(wù)來(lái)處理應(yīng)用程序完整的數(shù)據(jù)模型可能是相當(dāng)費(fèi)時(shí)的,正如這個(gè)例子中顯示的,特殊特性的操作可能導(dǎo)致Web Service非常臃腫,換句話說(shuō),Web Service將有新的要求和操作要增加,甚至包括不屬于核心業(yè)務(wù)域的操作。

在例1中你看到GetAllProductsWithCategories操作默認(rèn)用于檢索Product和分類。即使添加排序、過(guò)濾和分頁(yè)機(jī)制到這個(gè)簡(jiǎn)單的例子你也不要感到驚訝,如果有一個(gè)簡(jiǎn)單的方法支持?jǐn)?shù)據(jù)操作(如查詢、排序、過(guò)濾等)不用每次都手動(dòng)構(gòu)建這些機(jī)制那將是非常吸引人的,ADO.NET Data Service就正是為此而生的。

ADO.NET Data Service

ADO.NET Data Service的目標(biāo)是為數(shù)據(jù)模型提供Web訪問(wèn)端點(diǎn),這些端點(diǎn)提供了數(shù)據(jù)排序、過(guò)濾、調(diào)整和分頁(yè)功能,因此開(kāi)發(fā)人員就不需要在自己去編寫(xiě)這部分代碼了,實(shí)際上,每個(gè)端點(diǎn)都是LINQ查詢的起點(diǎn),就從這個(gè)端點(diǎn)上你就可以查詢你想要查找的數(shù)據(jù)。

但不要認(rèn)為ADO.NET Data Service是另一個(gè)數(shù)據(jù)訪問(wèn)策略,實(shí)際上,ADO.NET Data Service不執(zhí)行任何直接的數(shù)據(jù)訪問(wèn)操作,它位于數(shù)據(jù)訪問(wèn)的上層,圖1顯示了ADO.NET Data Service和它在一個(gè)應(yīng)用程序架構(gòu)中的位置。

 

圖 1 ADO.NET Data Service層

由于ADO.NET Data Service依賴于數(shù)據(jù)訪問(wèn)程序完成真實(shí)的數(shù)據(jù)訪問(wèn)工作,你必須指定這個(gè)方法該如何做,在ADO.NET Data Service中,每個(gè)服務(wù)(Service)必須回到開(kāi)啟LINQ的提供程序的后面,實(shí)際上,每個(gè)端點(diǎn)就是一個(gè)Iqueryable端點(diǎn),因此ADO.NET Data Service支持任何支持Iqueryable的對(duì)象。

創(chuàng)建服務(wù)(Service)

當(dāng)你將ADO.NET Data Service添加到你的項(xiàng)目中時(shí),會(huì)創(chuàng)建一個(gè)新的.svc文件,代表一個(gè)服務(wù)的類,和Web Service不同,你不需要自己親自實(shí)現(xiàn)服務(wù)的操作,但要允許DataService類處理這些工作,為了運(yùn)行這些服務(wù),有兩個(gè)小任務(wù)必須執(zhí)行。首先,DataService類需要一個(gè)類型參數(shù)叫做上下文對(duì)象,它是將數(shù)據(jù)作為服務(wù)暴露的類,當(dāng)你的服務(wù)從關(guān)系數(shù)據(jù)庫(kù)暴露數(shù)據(jù)時(shí),這個(gè)類是從實(shí)體框架(EntityFramework)的ObjectContext或LINQ to SQL的DataContext衍生而來(lái)的。

//使用我的NorthwindEntities上下文對(duì)象(context object)作為服務(wù)(Service)的數(shù)據(jù)源

public class Products : DataService

上下文對(duì)象沒(méi)有基數(shù)類要求,實(shí)際上,你可以創(chuàng)建你自己的上下文對(duì)象,只要它的屬性實(shí)現(xiàn)了Iqueryable接口,ADO.NET Data Service將會(huì)以端點(diǎn)形式暴露這些屬性:

public class StateContext
{
  StateList _states = new StateList();
  public IQueryable States 
  {
    get { return _states.AsQueryable(); } 
  }
}

InitializeService調(diào)用中,你可以使用IdataServiceConfiguration對(duì)象指定什么類型的許可允許進(jìn)入服務(wù),ADO.NET Data Service使用名詞和動(dòng)詞具體指定許可,如例2所示:

例2 設(shè)置訪問(wèn)規(guī)則

//這個(gè)方法只被調(diào)用一次初始化服務(wù)端策略
public static void InitializeService(IDataServiceConfiguration config)
{
  //只允許我們讀取和更新Products實(shí)體,不允許刪除和創(chuàng)建
  config.SetEntitySetAccessRule("Products", 
                                EntitySetRights.AllRead | 
                                EntitySetRights.WriteUpdate);
  //只允許讀取Category和Suppliers實(shí)體
  config.SetEntitySetAccessRule("Categories", EntitySetRights.AllRead);
  config.SetEntitySetAccessRule("Suppliers", EntitySetRights.AllRead);
}

完成這個(gè)之后,你可以直接瀏覽服務(wù)了,它將會(huì)顯示每個(gè)端點(diǎn)的原子反饋信息,為了調(diào)試ADO.NET Data Service,我建議你禁用Internet Explorer的RSS 反饋視圖,或使用另一個(gè)瀏覽器查看服務(wù)的XML格式。

#p#

查詢和更新數(shù)據(jù)

ADO.NET Data Service將服務(wù)作為具有代表性的狀態(tài)轉(zhuǎn)換器(Representational State Transfer (REST))暴露,它是一個(gè)基礎(chǔ)服務(wù),不是基于SOAP的服務(wù),這意味著要替換掉SOAP封包,服務(wù)響應(yīng)的有效負(fù)載只包括數(shù)據(jù),不包括原數(shù)據(jù)(metadata),所有請(qǐng)求都使用HTTP動(dòng)詞(GET,PUT,POST等)和請(qǐng)求URI描述,假定你有一個(gè)如圖2所示的模型描述Products,Categories和Suppliers,ADO.NET Data Service服務(wù)將會(huì)產(chǎn)生三個(gè)端點(diǎn),每個(gè)實(shí)體集一個(gè),URI為了確定一個(gè)模型中的實(shí)體集,只需要使用服務(wù)的地址和端點(diǎn)的名字就可以了:http://localhost/{服務(wù)名}/{端點(diǎn)名}或http://localhost/Product.svc/Products。

圖 2 數(shù)據(jù)模型示例

URI語(yǔ)法支持許多不同的特性,包括檢索特殊的實(shí)體,對(duì)結(jié)果進(jìn)行排序、過(guò)濾、分頁(yè)和調(diào)整。

ADO.NET Data Service使用這些URI風(fēng)格的查詢將數(shù)據(jù)返回給服務(wù)的用戶,目前支持兩個(gè)序列化格式(將來(lái)的版本很可能會(huì)進(jìn)行擴(kuò)展):JavaScript對(duì)象標(biāo)記(JavaScript Object Notation即JSON)和基于原子的XML(Atom-based XML)。JSON對(duì)于客戶端Web代碼非常有吸引力,而Atom是基于XML的格式,因此需要借助XML解析器。

ADO.NET Data Service在查詢中使用標(biāo)準(zhǔn)的HTTP訪問(wèn)頭來(lái)確定向客戶端返回什么格式,如果你從客戶端(如一個(gè)瀏覽器)發(fā)出一個(gè)請(qǐng)求可以破壞XML,如果你不通過(guò)Accept頭指定一個(gè)優(yōu)先選用的格式,默認(rèn)將使用Atom作為返回的格式。

查詢數(shù)據(jù)只是解決方案的一部分,我們的最終目標(biāo)是同時(shí)支持查詢和更新,為了支持這些要求,ADO.NET Data Service映射了四個(gè)最基本的數(shù)據(jù)訪問(wèn)操作到基本的HTTP動(dòng)詞(如表1所示):

數(shù)據(jù)訪問(wèn)動(dòng)詞 HTTP動(dòng)詞
Create POST
Read GET
Update PUT
Delete DELETE

表 1 數(shù)據(jù)訪問(wèn)動(dòng)詞 vs HTTP動(dòng)詞

通過(guò)使用這些動(dòng)詞,ADO.NET Data Service讓服務(wù)的用戶可以利用所有的數(shù)據(jù)操作類型,而不用為不同類型創(chuàng)建專門(mén)的端點(diǎn)。使用ADO.NET Data Service更新數(shù)據(jù)的唯一要求是在數(shù)據(jù)訪問(wèn)技術(shù)下支持Iupdatable接口,這個(gè)接口定義了如何從ADO.NET Data Service更新和傳播到數(shù)據(jù)源。

Silverlight 2.0客戶端庫(kù)

如果你使用ADO.NET Data Service通過(guò)URI語(yǔ)法和操作XML來(lái)進(jìn)行查詢和更新數(shù)據(jù),你可能會(huì)得到你想要的許多功能,但你仍然要自行構(gòu)建一些管道,ADO.NET Data Service客戶端庫(kù)的引入就是要解決這個(gè)問(wèn)題,這個(gè)庫(kù)允許你直接在Silverlight程序中進(jìn)行LINQ查詢,由客戶端庫(kù)將LINQ查詢翻譯成HTTP查詢或更新請(qǐng)求。

首先,你需要生成一些代碼,這些代碼讀取ADO.NET Data Service服務(wù)的元數(shù)據(jù),并為服務(wù)的實(shí)體生成數(shù)據(jù)類。

為了生成這些代碼,你需要在你的項(xiàng)目(Project)中添加Service Reference,你可以在項(xiàng)目資源管理器(Project Explorer)中Silverlight項(xiàng)目上點(diǎn)擊右鍵,然后選擇‘添加服務(wù)引用(即Add Service Reference)’,在彈出的對(duì)話框中點(diǎn)擊‘查找(Discover)’按鈕,顯示你項(xiàng)目中的服務(wù)(包括ADO.NET Data Service),選擇ADO.NET Data Service端點(diǎn),點(diǎn)擊確定按鈕。這樣會(huì)創(chuàng)建一個(gè)新的文件,包含了每個(gè)端點(diǎn)對(duì)應(yīng)的data contract類和一個(gè)DataServiceContext衍生類,DataServiceContext類用作服務(wù)接入點(diǎn)(暴露可查詢的服務(wù)端點(diǎn)),這樣會(huì)在你的Silverlight項(xiàng)目中包含這些類,并在System.Data.Services.Client.dll(Silverlight 2 SDK的一部分)中添加一個(gè)引用。Silverlight客戶端代碼和其它使用.NET的代碼基于LINQ的查詢非常相似,下面是示例代碼:

// 創(chuàng)建服務(wù)類指定ADO.NET Data Service的位置
 NorthwindEntities ctx = 
  new NorthwindEntities(new Uri("Products.svc", UriKind.Relative));
//創(chuàng)建LINQ查詢
var qry = from p in ctx.Products
               orderby p.ProductName
                select p;

當(dāng)你執(zhí)行這個(gè)查詢時(shí),它會(huì)直接向目標(biāo)數(shù)據(jù)發(fā)送一個(gè)Web請(qǐng)求,但這里的Silverlight代碼和標(biāo)準(zhǔn)的LINQ查詢不同,在Silverlight中不允許同步Web請(qǐng)求,因此,如果要執(zhí)行異步,你首先需要將查詢轉(zhuǎn)換成DataServiceQuery對(duì)象,然后再調(diào)用BeginExecute啟動(dòng)異步執(zhí)行:

// 創(chuàng)建一個(gè)DataServiceQuery,因?yàn)椴樵兎祷氐氖荘roducts
DataServiceQuery productQuery =
  (DataServiceQuery)qry;
//指定一個(gè)callback函數(shù)執(zhí)行異步查詢
  productQuery.BeginExecute(new 
    AsyncCallback(OnLoadComplete),
    productQuery);

當(dāng)這些查詢執(zhí)行完后,無(wú)論操作是否成功,在AsyncCallback中指定的方法都會(huì)執(zhí)行,通常你會(huì)在AsyncCallback中包含原始查詢,因此可以在callback方法中檢索它,你也可以將其保存為類的一部分,正如你在例3中看到的:

例3 將結(jié)果添加到集合中

void OnLoadComplete(IAsyncResult result)
{
  //為查詢獲取一個(gè)引用
  DataServiceQuery productQuery =
    (DataServiceQuery)result.AsyncState;
 
  try
  {
    //獲得結(jié)果并將其添加到集合中
    List products = productQuery.EndExecute(result).ToList();
 
  }
  catch (Exception ex)
  {
    if (HtmlPage.IsEnabled)
    {
      HtmlPage.Window.Alert("Failed to retrieve data: " + ex.ToString());
    }
  }
 
}

如果你以前還沒(méi)有處理過(guò)LINQ,理解這些模型可能就非常困難,在寫(xiě)本文的時(shí)候,除了在異步包中執(zhí)行LINQ(如ThreadPool和BackgroundWorker)外,還沒(méi)有關(guān)于異步LINQ很好的模型,Silverlight需要所有的請(qǐng)求都是異步的,因此在使用ADO.NET Data Service客戶端庫(kù)時(shí)需要使用這個(gè)模型。

載入相關(guān)實(shí)體

ADO.NET Data Service也允許你選擇如何載入相關(guān)的實(shí)體,在前面的例子中,我是從服務(wù)器中載入Products(產(chǎn)品)的,每個(gè)產(chǎn)品與供應(yīng)商都有一個(gè)關(guān)系。使用前面的LINQ查詢,我們只檢索了產(chǎn)品,如果我還想顯示供應(yīng)商和分類信息,我們可以按需載入相關(guān)信息,也可以在原始查詢中明確地從服務(wù)器去檢索,這兩種技術(shù)各有各的優(yōu)勢(shì),但如果你清楚地知道需要顯示哪些信息,明確地載入可能更有效,如果你只想為一些實(shí)體載入數(shù)據(jù),使用按需檢索可能會(huì)更好。

默認(rèn)情況下,如果你沒(méi)有明確地載入屬性,關(guān)系屬性(如產(chǎn)品供應(yīng)商)就是空的,為便于按需載入,DataServiceContext類有一個(gè)BeginLoadProperty方法(遵循相同的異步模式)可以指定源實(shí)體,屬性名和callback。

public void LoadSupplierAsync(Product theProduct)
{
  TheContext.BeginLoadProperty(theProduct,
                               "Supplier",
                               new AsyncCallback(SupplierLoadComplete),
                               null);
  }

  public void SupplierLoadComplete(IAsyncResult result)
  {
    TheContext.EndLoadProperty(result);
  }

調(diào)用EndLoadProperty后,屬性和相關(guān)的實(shí)體就被正確地載入,在許多情況下,你可能想在原始查詢中明確地載入它們,因?yàn)槿绱?,LINQ提供者支持Expand擴(kuò)展方法,這個(gè)方法允許你指定屬性的名稱路徑便于查詢執(zhí)行時(shí)載入它們,Expand方法在LINQ查詢的from子句中使用,它告訴提供者視圖載入這些相關(guān)實(shí)體,例如,如果你使用Expand方法改變了Category 和 Supplier原始查詢,在原始查詢執(zhí)行期間,我們的對(duì)象將會(huì)載入這些相關(guān)實(shí)體:

var qry =
  from p in TheContext.Products.Expand("Supplier").Expand("Category")
          orderby p.ProductName
          select p;

如果你使用ADO.NET Data Service讀取數(shù)據(jù),知道如何創(chuàng)建一個(gè)查詢,運(yùn)行它,載入你想要的相關(guān)實(shí)體。如果你需要真實(shí)地修改數(shù)據(jù),只需要將你的新數(shù)據(jù)綁定到你的Silverlight控制器即可。

#p#

變化管理

ADO.NET Data Service客戶端庫(kù)不支持對(duì)象的自動(dòng)變更監(jiān)視,這意味著當(dāng)對(duì)象,集合和關(guān)系發(fā)生變化時(shí),需要開(kāi)發(fā)人員告訴DataServiceContext這些變化,通知DataServiceContext對(duì)象的API相當(dāng)簡(jiǎn)單,如例4所示:

例4 DataServiceContext變更API

方法 描述
AddObject 添加一個(gè)新創(chuàng)建的對(duì)象
UpdateObject 標(biāo)記一個(gè)已經(jīng)變化的對(duì)象
DeleteObject 標(biāo)記一個(gè)刪除的對(duì)象
AddLink 在兩個(gè)對(duì)象之間添加一個(gè)鏈接
UpdateLink 更新兩個(gè)對(duì)象之間的鏈接
DeleteLink 刪除兩個(gè)對(duì)象之間的鏈接

這意味著你要監(jiān)視對(duì)象的變化,并在你自己的代碼中通知DataServiceContext對(duì)象,表面上看起來(lái)這樣讓人很失望,因?yàn)闆](méi)有實(shí)現(xiàn)自動(dòng)化的變化管理,但這樣可以讓庫(kù)變得更有效也更mini。

你可能會(huì)對(duì)如何監(jiān)視對(duì)象的變化感到奇怪,答案就是生成的代碼中,在每個(gè)生成的data contract類中,當(dāng)類中的數(shù)據(jù)變化時(shí)partial方法被調(diào)用,如果這些方法從來(lái)沒(méi)有使用過(guò),它們本身不會(huì)造成任何資源消耗,你可以在任何支持變化通知的data contracts上使用partial方法機(jī)制,只需要在partial方法中調(diào)用DataServiceContract即可,不用連接DataServiceContract整個(gè)類。

幸運(yùn)的是,Silverlight已經(jīng)有一個(gè)接口支持變化通知了(INotifyPropertyChange),通過(guò)這個(gè)接口可以在你的實(shí)現(xiàn)中將任何變化通知給感興趣的人,例如你可以在你的data contract類(在我們的例子中是Product類)中調(diào)用InotifyPropertyChange定義一個(gè)事件,當(dāng)數(shù)據(jù)發(fā)生變化時(shí)可以激活它,下面就是具體的示例:

public partial class Product : INotifyPropertyChanged
{
  public event PropertyChangedEventHandler PropertyChanged;
}

這樣當(dāng)任何屬性發(fā)生變化時(shí)都可以觸發(fā)一個(gè)事件,你可以通過(guò)partial方法決定什么時(shí)候觸發(fā)這個(gè)事件,例如,當(dāng)ProductName發(fā)生變化時(shí)要通知預(yù)定人,只需要調(diào)用OnProductNameChanged方法,然后觸發(fā)PropertyChanged事件,傳遞ProductName通知變化的屬性給事件預(yù)定人,下面是代碼:

partial void OnProductNameChanged()
{
  if (PropertyChanged != null)
  {
    PropertyChanged(this, new PropertyChangedEventArgs("ProductName"));
  } 
}

通過(guò)在這些可寫(xiě)的屬性上調(diào)用這些partial方法,監(jiān)視你對(duì)象的變化就很簡(jiǎn)單了,當(dāng)對(duì)象發(fā)生變化時(shí),你可以注冊(cè)PropertyChanged事件然后通知DataServiceContext對(duì)象:

//在OnLoadComplete方法中,獲取結(jié)果然后將它們添加到集合中
List products = productQuery.EndExecute(result).ToList();
foreach (Product product in products)
{
  //觸發(fā)變化通知
  product.PropertyChanged +=
    new PropertyChangedEventHandler(product_PropertyChanged);
}

 

最后你可以調(diào)用product_PropertyChanged方法通知DataServiceContext對(duì)象:

void product_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
  Product product = (Product)sender;
  TheContext.UpdateObject(product);
}

同樣,在創(chuàng)建對(duì)象或刪除對(duì)象時(shí)也需要通知DataServiceContext,如:

void addNewButton_Click(object sender, RoutedEventArgs e)
{
  Product theProduct = new Product();
  // ...
  TheContext.AddObject(theProduct);
}
 
void deleteButton_Click(object sender, RoutedEventArgs e)
{
  Product theProduct = (Product)theList.SelectItem;
  TheContext.DeleteObject(theProduct);
  theCollection.Remove(theProduct);
}

在這些代碼中,你可以在你的Silverlight UI中修改這些對(duì)象,讓數(shù)據(jù)綁定和變化通知代碼確保讓DataServiceContext知道所有變化都會(huì)引發(fā)什么后果,但你如何對(duì)這些服務(wù)執(zhí)行真實(shí)的更新呢?

通過(guò)服務(wù)更新

現(xiàn)在你的DataServiceContext對(duì)象已經(jīng)知道數(shù)據(jù)的變化,但還需要一個(gè)方法通知給服務(wù)器,為了解決這個(gè)問(wèn)題,DataServiceContext類提供了一個(gè)BeginSaveChanges方法,它和本文前面描述的查詢都使用了相同的異步方法,BeginSaveChanges方法將所有變化都吸收進(jìn)DataServiceContext,并將它們發(fā)送給服務(wù)器:

TheContext.BeginSaveChanges(SaveChangesOptions.None,

new AsyncCallback(OnSaveAllComplete),

null);

調(diào)用BeginSaveChanges時(shí),有一個(gè)標(biāo)志枚舉調(diào)用SaveChangesOptions,這個(gè)枚舉允許你指定兩個(gè)選項(xiàng):是否使用批處理,是否繼續(xù),即使某些變化保存失敗。通常,我建議使用批處理,實(shí)際上,在某些父/子關(guān)系類型上批處理是必須的,因?yàn)楦缸又g可能使用了引用完整性約束,這樣更新才能保證父子之間的一致性。

保存完畢時(shí),將會(huì)執(zhí)行callback,有兩個(gè)機(jī)制可以傳播錯(cuò)誤消息給你,首先,如果在執(zhí)行保存時(shí)出現(xiàn)了異常,當(dāng)你在調(diào)用EndSaveChanges時(shí),會(huì)拋出異常,因?yàn)槿绱?,你可能想要使用try/catch來(lái)捕獲災(zāi)難性的錯(cuò)誤;另外,EndSaveChanges返回的類型是一個(gè)DataServiceResponse對(duì)象,DataServiceResponse有一個(gè)HasErrors屬性,但在Silverlight 2 Beta 2版本庫(kù)中它還不夠安全:

void OnSaveAllComplete(IAsyncResult result)
{
  bool succeeded = true;
  try
  {
    DataServiceResponse response = 
      (DataServiceResponse)TheContext.EndSaveChanges(result);
 
    foreach (OperationResponse opResponse in response)
    {
      if (opResponse.HasErrors)
      {
        succeeded = false;
      }
    }
 
  }
  catch (Exception ex)
  {
    succeeded = false;
  }
 
  // Alert the User
}

你可以重復(fù)使用OperationResponse對(duì)象來(lái)查看是否出現(xiàn)了錯(cuò)誤,DataServiceResponse是OperationResponse對(duì)象的一個(gè)集合,在以后的版本中,你應(yīng)該可以依賴于DataServiceResponse類自身的HasErrors屬性了。

服務(wù)調(diào)式

在調(diào)試服務(wù)時(shí),你要執(zhí)行三個(gè)重要的任務(wù):查看DataServiceContext對(duì)象中數(shù)據(jù)的狀態(tài),查看ADO.NET Data Services產(chǎn)生的請(qǐng)求,以及捕獲服務(wù)器錯(cuò)誤。

首先我們處理DataServiceContext對(duì)象中的實(shí)體狀態(tài),DataServiceContext類暴露了兩個(gè)有用的集合:Entities和Links,這些集合是只讀的,由DataServiceContext進(jìn)行跟蹤,在調(diào)式時(shí),不管你是將對(duì)象標(biāo)記為已變化還是未變化,在調(diào)試器中查看這些集合是非常有用的,可以幫助你確定跟蹤思路是不是正確的。

注意對(duì)你而言,查看你的Silverlight 2程序?qū)Ψ?wù)器的真實(shí)請(qǐng)求也是很重要的,最好的方法是使用網(wǎng)絡(luò)代理,我個(gè)人使用的是Fiddler2,如果你對(duì)Fiddler2不熟悉,也可以使用Web traffic之類的工具來(lái)捕獲數(shù)據(jù)包,查看真正發(fā)生了什么。

對(duì)于ADO.NET Data Service而言,你可能想查看你在線上傳來(lái)傳去的都是什么,即Silverlight程序發(fā)出的數(shù)據(jù)和接收到的數(shù)據(jù),可以去我的博客(http://wildermuth.com/2008/06/07/Debugging_ADO_NET_Data_Services_with_Fiddler)轉(zhuǎn)轉(zhuǎn)。

最后,.NET Framework 3.5 SP1不會(huì)將服務(wù)端錯(cuò)誤傳遞給客戶端了,實(shí)際上,服務(wù)器上的大部分錯(cuò)誤都是服務(wù)器吞下去的,調(diào)試服務(wù)端錯(cuò)誤的最好辦法是在調(diào)試菜單(Debug->Exceptions…)中使用Exception選項(xiàng),配置調(diào)試器停止一切.NET異常,如果你選擇了這個(gè)選項(xiàng),你可以通過(guò)服務(wù)看到拋出的異常。

我在本文的目標(biāo)是展示ADO.NET Data Service是如何在Silverlight 2和基于服務(wù)的模塊之間建立起連接的,現(xiàn)在你應(yīng)該已經(jīng)知道如何使用ADO.NET Data Service從服務(wù)器讀取數(shù)據(jù)和往服務(wù)器寫(xiě)數(shù)據(jù)了,再也不用自己動(dòng)手設(shè)計(jì)Web Service了,正如你所看到的,Silverlight、ADO.NET Data Service和LINQ三者的組合讓你可以創(chuàng)建強(qiáng)大的基于數(shù)據(jù)驅(qū)動(dòng)的Web應(yīng)用程序,具有Web 2.0技術(shù)的所有有點(diǎn)。

 

【編輯推薦】

  1. LINQ to SQL實(shí)現(xiàn)數(shù)據(jù)訪問(wèn)通用基類
  2. SQL連接中加條件查詢的LINQ表達(dá)式寫(xiě)法
  3. 圖解Silverlight 3的7個(gè)新功能
責(zé)任編輯:彭凡 來(lái)源: 51CTO
相關(guān)推薦

2009-08-13 11:22:59

LINQ和ADO.NE

2009-09-14 13:37:25

LINQ ADO.NE

2009-12-29 16:12:25

ADO程序員

2009-12-28 15:11:36

ADO.NET專家

2009-12-25 10:25:59

2009-12-29 14:09:17

ADO.NET通用接口

2009-12-24 14:06:22

ADO.NET 應(yīng)用程

2009-12-24 15:18:42

創(chuàng)建ADO.NET

2009-11-12 13:26:56

使用ADO.NET參數(shù)

2009-12-23 17:30:54

ADO.NET應(yīng)用程序

2009-12-21 17:35:24

ADO.NET對(duì)象

2009-12-21 16:45:41

ADO.NET程序

2009-12-25 17:05:32

ADO.NET數(shù)據(jù)庫(kù)

2009-11-13 09:45:54

ADO.NET程序集

2009-12-21 17:23:56

ADO.Net程序

2009-12-24 14:45:32

ADO.NET程序

2009-12-22 15:03:51

ADO.NET使用

2011-05-20 17:05:59

ADO.NET

2012-05-10 11:25:34

LINQ

2009-10-29 10:34:31

ADO.NET使用技巧
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)