轉(zhuǎn)帖|其它|編輯:郝浩|2010-08-09 11:25:47.000|閱讀 709 次
概述:
# 界面/圖表報(bào)表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
OData開放數(shù)據(jù)協(xié)議是微軟針對(duì)Google的GData推出的,旨在推廣Web程序數(shù)據(jù)庫(kù)格式標(biāo)準(zhǔn)化的開放數(shù)據(jù)協(xié)議,微軟將 OData 定義為基于 HTTP、AtomPub 和 JSON 的協(xié)議,增強(qiáng)各種網(wǎng)頁(yè)應(yīng)用程序之間的數(shù)據(jù)兼容性,以提供多種應(yīng)用、服務(wù)和數(shù)據(jù)商店的信息訪問(wèn)。并且,微軟已經(jīng)正式推出了 OData SDK,包含了 .net、Java、PHP、Palm WebOS 和 iPhone 的支持。其中 .Net OData 客戶端基于 Apache 授權(quán)開源。微軟多款產(chǎn)品已經(jīng)支持 OData 包括 SharePoint Server 2010, Excel 2010, Dynamics 等。
微軟第一代數(shù)據(jù)交換協(xié)議叫ODBC(開放數(shù)據(jù)庫(kù)聯(lián)接 Open Database Connectivity),目前仍舊可見(jiàn)于window和Linux的原生程序開發(fā)之中,其目的是為操作系統(tǒng)下的應(yīng)用程序之間提供統(tǒng)一的數(shù)據(jù)交互的 API,是函數(shù)式的。之后,微軟推出了第二代:OLE DB,帶來(lái)了OOP式樣的交互API,以及跨網(wǎng)絡(luò)的數(shù)據(jù)交互的可能性(通過(guò)DCOM),OLE DB 標(biāo)準(zhǔn)的具體實(shí)現(xiàn)是一組C++ API 函數(shù),就像ODBC 標(biāo)準(zhǔn)中的ODBC API 一樣,不同的是,OLE DB 的API 是符合COM 標(biāo)準(zhǔn)、基于對(duì)象的(ODBC API 則是簡(jiǎn)單的C API)。使用OLE DB API,可以編寫能夠訪問(wèn)符合OLE DB 標(biāo)準(zhǔn)的任何數(shù)據(jù)源的應(yīng)用程序,也可以編寫針對(duì)某種特定數(shù)據(jù)存儲(chǔ)的查詢處理程序(Query Processor)和游標(biāo)引擎(Cursor Engine),因此OLE DB 標(biāo)準(zhǔn)實(shí)際上是規(guī)定了數(shù)據(jù)使用者和提供者之間的一種應(yīng)用層的協(xié)議(Application-Level Protocol)。在云計(jì)算時(shí)代,web應(yīng)用已經(jīng)是主流,程序主要通過(guò)HTTP Request來(lái)表達(dá)需求,通過(guò)HTTP Response來(lái)獲取結(jié)果,ODBC和OLE DB都已無(wú)法使用。微軟于是開發(fā)了其第三代數(shù)據(jù)交互協(xié)議:OData開放數(shù)據(jù)協(xié)議
在SOA的世界中,最重要的一個(gè)概念就是契約(contract)。在云計(jì)算的世界中,有關(guān)通信的最重要的概念也是契約。XML具有強(qiáng)大對(duì)數(shù)據(jù)的描述能力,Atom格式和AtomPub都建立在XML之上,在Google和微軟的推動(dòng)下,也已經(jīng)成為標(biāo)準(zhǔn)。但是,Atom/AtomPub和ODBC /OLEDB這樣的真正數(shù)據(jù)交互協(xié)議相比較,還有著根本上的欠缺:缺乏數(shù)據(jù)類型的具體描述,降低了交互性能。缺乏對(duì)數(shù)據(jù)查詢的控制能力,比如返回特定的數(shù)據(jù)集合的區(qū)間,或者說(shuō)分頁(yè)能力等等。微軟基于EDM模型釋出了:OData,這里也可以看出Entity Framework對(duì)于NHibernate這樣的ORM的工具不同的戰(zhàn)略考慮。
在PDC大會(huì)上,微軟宣布了一個(gè)代號(hào)為 “Dallas”的社區(qū)技術(shù)預(yù)覽(CTP),由Windows Azure 和SQL Azure構(gòu)建的信息服務(wù),能夠讓開發(fā)者與信息工作者在任何平臺(tái)上使用優(yōu)質(zhì)的第三方數(shù)據(jù)集和內(nèi)容。“Dallas”也可以通過(guò)使用微軟技術(shù)自助的商務(wù)智能與分析存儲(chǔ)的數(shù)據(jù)集。Dallas所使用的數(shù)據(jù)交互協(xié)議就是OData。
在微軟的解決方案中,是用WCF來(lái)處理所有程序間的通信,針對(duì)數(shù)據(jù)通信,WCF Data Services自然是最好的選擇。首先,WCF Data Services是WCF服務(wù),所以你可以使用所有現(xiàn)有的WCF知識(shí)。其次,WCF Data Services已經(jīng)實(shí)現(xiàn)了OData拓?fù)洌谑悄憧梢灾铝τ谀愕臄?shù)據(jù)格式在你的程序中的表示,而不是AtomPub/JSON這些真正在網(wǎng)絡(luò)上傳遞的數(shù)據(jù)格式。再有,WCF Data Services致力于數(shù)據(jù)傳輸,而不是數(shù)據(jù)存儲(chǔ)。你的數(shù)據(jù)可以存放在任何位置:本地的數(shù)據(jù)庫(kù),云端的數(shù)據(jù)庫(kù),外部的Web Services,xml文件,等等。無(wú)論數(shù)據(jù)是怎么來(lái)的,你都可以用同樣的方式來(lái)發(fā)布/使用它們。
下面我們就使用WCF Data Service將服務(wù)器的Windows應(yīng)用程序日志向外發(fā)布。我們的應(yīng)用程序可以把日志直接就寫在Windows的日志里,然后通過(guò)使用WCF Data Service非常容易的就將日志想其他需要的用戶公開。WCF Data Service默認(rèn)使用的是Entity Framework,使用Entity Framework參看文章WCF Data Service QuickStart,還有一個(gè)Reflection Provider,可以支持只讀的數(shù)據(jù)服務(wù),這個(gè)例子就是演示使用Reflection Provider,資料參看MSDN://msdn.microsoft.com/en-us/library/dd723653(VS.100).ASPx,還可以自定義實(shí)現(xiàn)一個(gè)Provider,參看文章自定義Data Service Providers。
首先定義一個(gè)Windows日志的實(shí)體,類似于WCF的DataContract,這里使用的是EDM的映射:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Services.Common;
namespace ReflectionDataServiceDemo
{
[EntityPropertyMappingAttribute("Source",
SyndicationItemProperty.Title,
SyndicationTextContentKind.Plaintext, true)]
[EntityPropertyMapping("Message",
SyndicationItemProperty.Summary,
SyndicationTextContentKind.Plaintext, true)]
[EntityPropertyMapping("TimeGenerated",
SyndicationItemProperty.Updated,
SyndicationTextContentKind.Plaintext, true)]
[DataServiceKey("EventID")]
public class LogEntry
{
public long EventID
{
get;
set;
}
public string Category
{
get;
set;
}
public string Message
{
get;
set;
}
public DateTime TimeGenerated
{
get;
set;
}
public string Source
{
get;
set;
}
}
}
上面使用一個(gè)新特性Friendly feeds 將數(shù)據(jù)映射到標(biāo)準(zhǔn)ATOM元素,其中DataServiceKey是唯一一個(gè)必須的標(biāo)記,然后使用Reflection Provider實(shí)現(xiàn)一個(gè)IQueryable接口的數(shù)據(jù)源:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Diagnostics;
namespace ReflectionDataServiceDemo
{
public class LogDataSource
{
string source;
public LogDataSource(string source)
{
this.source = source;
}
public LogDataSource()
{
}
public IQueryable<LogEntry> LogEntries
{
get { return GetEntries().AsQueryable().OrderBy(e => e.TimeGenerated); }
}
private IEnumerable<LogEntry> GetEntries()
{
var applicationLog = System.Diagnostics.EventLog.GetEventLogs().Where(e => e.Log == "Application")
.FirstOrDefault();
var entries = new List<LogEntry>();
if (applicationLog != null)
{
foreach (EventLogEntry entry in applicationLog.Entries)
{
if (source == null || entry.Source.Equals(source, StringComparison.InvariantCultureIgnoreCase))
{
entries.Add(new LogEntry
{
Category = entry.Category,
EventID = entry.InstanceId,
Message = entry.Message,
TimeGenerated = entry.TimeGenerated,
Source = entry.Source,
});
}
}
}
return entries.OrderByDescending(e => e.TimeGenerated)
.Take(200);
}
}
}
最后添加一個(gè)WCF Data Service,代碼非常的簡(jiǎn)單,主要的工作就是將上述數(shù)據(jù)源通過(guò)WCF Data Service發(fā)布出去:
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.Configuration;
namespace ReflectionDataServiceDemo
{
public class LogDataService : DataService<LogDataSource >
{
// This method is called only once to initialize service-wide policies.
public static void InitializeService(DataServiceConfiguration config)
{
// TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc.
// Examples:
config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);
config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
}
protected override LogDataSource CreateDataSource()
{
string source = ConfigurationManager.AppSettings["EventLogSource"];
if (source == null)
{
throw new ApplicationException("The EventLogSource appsetting is missing in the configuration file");
}
return new LogDataSource(source);
}
}
}
我們?cè)賮?lái)寫個(gè)簡(jiǎn)單控制臺(tái)客戶端消費(fèi)這個(gè)Service,通過(guò)Visual Studio的添加服務(wù)引用生成服務(wù)的客戶端代碼,還可以使用一個(gè)插件Open Data Protocol Visualizer查看服務(wù)返回的OData數(shù)據(jù)數(shù)據(jù),這個(gè)工具的獲取和安裝可以參看VS2010的擴(kuò)展。可以通過(guò)服務(wù)引用的“View in Diagram”進(jìn)行查看。
客戶端的代碼也非常簡(jiǎn)單;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ClientDemo
{
class Program
{
static void Main(string[] args)
{
LogDataService.LogDataSource logSource = new LogDataService.LogDataSource(new Uri("//localhost:3399/LogDataService.sVC/"));
foreach (var item in logSource.LogEntries)
{
Console.WriteLine(string.Format("來(lái)自{0}事件{1},內(nèi)容{2}", item.Source, item.EventID, item.Message));
}
Console.Read();
}
}
}
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請(qǐng)務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請(qǐng)郵件反饋至chenjj@fc6vip.cn
文章轉(zhuǎn)載自:博客轉(zhuǎn)載