Entity Framework技巧系列之十四 - Tip 56
提示56. 使用反射提供程序编写一个OData Service
在TechEd我收到一大堆有关将数据作为OData暴露的问题。
到目前为止你大概知道可以使用数据服务与Entity Framework将数据库中的数据暴露为一个OData服务。你可能还知道你可以在数据服务中使用一个自定义的数据服务提供程序来由任意地方暴露任意数据。
但是你了解数据服务反射提供程序吗?
事实上反射提供程序的使用非常简单。
我将创建一个OData服务暴露一些内存中的数据来展示这有多么容易。
首先你需要一些数据,这部分数据如何:
1 [EntityPropertyMapping("Name", 2 SyndicationItemProperty.Title, 3 SyndicationTextContentKind.Plaintext, 4 false)] 5 [EntityPropertyMapping("Odds", 6 SyndicationItemProperty.Summary, 7 SyndicationTextContentKind.Plaintext, 8 false)] 9 public class Team { 10 public static List<Team> Teams = new List<Team>{ 11 new Team {ID = 1, Name = "New Zealand", Odds = "1:1000"}, 12 new Team {ID = 2, Name = "Paraquay", Odds = "1:50"}, 13 … }; 14 15 public int ID{get;set;} 16 public string Name {get;set;} 17 public string Odds { get; set; } 18 } 19 [DataServiceKey("Name")] 20 [EntityPropertyMapping("Name", 21 SyndicationItemProperty.Title, 22 SyndicationTextContentKind.Plaintext, 23 false)] 24 public class Group 25 { 26 public static List<Group> Groups = new List<Group>{ 27 new Group { 28 Name = "A", 29 Teams = new List<Team>{ 30 Team.Teams[0], 31 Team.Teams[1], 32 Team.Teams[2], 33 Team.Teams[3] 34 } 35 }, 36 new Group { 37 Name = "B", 38 Teams = new List<Team>{ 39 Team.Teams[4], 40 Team.Teams[5], 41 Team.Teams[6], 42 Team.Teams[7] 43 } 44 }, 45 … 46 }; 47 public string Name {get;set;} 48 public List<Team> Teams {get;set;} 49 }
注意[DataServiceKey]与[EntityPropertyMapping]特性的使用:
- [DataServiceKey]通知Data Services那个(些)属性是键。这个仅当
- [EntityPropertyMapping]通知Data Services将属性映射到一个标准的atom元素。这不是必须得-但这是一个最佳实践-它使浏览器中最终的源数据更易读。
下一步你需要一个类来扮演数据源。数据服务将暴露所有的IQueryable属性为源数据,并且推断出所有这些源数据暴露的类型所用到的类型。
所以如果我想要两个源,以暴露来自世界杯团体和小组,我将这样做:
1 public class WorldCupData 2 { 3 public IQueryable<Team> Teams{ 4 get{ 5 return Team.Teams.AsQueryable(); 6 } 7 } 8 public IQueryable<Group> Groups{ 9 get{ 10 return Group.Groups.AsQueryable(); 11 12 } 13 } 14 }
现在所有需要做的就是创建Data Service,并暴露出我们的数据集。只需向Web应用中添加一个WCF数据服务,并将自动生成的代码修改成如下这样:
1 public class WorldCup : DataService<WorldCupData> 2 { 3 // This method is called only once to initialize service-wide policies. 4 public static void InitializeService(DataServiceConfiguration config) { 5 config.SetEntitySetAccessRule("*", EntitySetRights.AllRead); 6 config.SetEntitySetPageSize("*", 100); 7 config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2; 8 } 9 }
完成后如下这样:
一些需要注意的点:
这个服务是只读的。如果你想要使它可写,你需要实现IDataServiceUpdateProvider接口。
在这个例子中,数据来自内存中的数组,然而如果你的数据源支持IQueryable接口,你的数据可以来自任何地方。
是的我知道这些数据都是错的,我正在新奥尔良到丹佛的西南航空的航班上,在没有互联网的情况下完成这些。谢天谢地这里有一个真实的世界杯OData Service。
编码愉快。