WCF 实例 —— 基于ADO.NET POCO Entity Framework的REST WCF

我们知道发布REST WCF服务时,为了跨语言要求服务的参数和返回值都是简单对象(POCO类)。但当结合ADO.NET Entities Framework时,这些EntityObject 却不是我们想要的简单对象。有没有别的办法发布一个简单对象?好在ADO.NET团队发布了一个ADO.NET POCO Entity Generator项目模板利用T4代码生成可以将EF的相对复杂的EntityObject转换成一个POCO类。使用方法可以看这里:http://blogs.msdn.com/b/adonet/archive/2010/01/25/walkthrough-poco-template-for-the-entity-framework.aspx

先看看不使用POCO Entity发布的REST WCF服务是怎样的情况。创建一个WCF Rest Application工程:
WCF 实例 —— 基于ADO.NET POCO Entity Framework的REST WCF_第1张图片
1. 准备:
创建一个 Northwind DB EF,并对应的创建一个REST服务:

[c-sharp]  view plain copy
  1. [WebGet(UriTemplate = "Shippers", ResponseFormat=WebMessageFormat.Xml)]  
  2. public List<Shippers> GetShippers()  
  3. {  
  4.     using (var db = new NorthwindEntities())  
  5.     {  
  6.         db.ContextOptions.LazyLoadingEnabled = false;  
  7.         db.ContextOptions.ProxyCreationEnabled = false;  
  8.         return db.Shippers.Take(10).ToList();  
  9.     }  
  10. }  

注意必须将 EF 的 LazyLoadingEnabled 和 ProxyCreationEnabled 都设为false,否则调用会出错。

2. 运行并查看一下返回的内容(使用Fiddler发起一个Http请求,查看Response(XML格式)):

明显在xml中多了很多EF定义的序列化信息。这对于客户端反序列化带来一定的难度,尤其是作为参数传递对象的时候,拼接这样格式的XML非常的麻烦。
WCF 实例 —— 基于ADO.NET POCO Entity Framework的REST WCF_第2张图片

再看看把上面的 ResponseFormat 改为 WebMessageFormat.Json 的结果:
WCF 实例 —— 基于ADO.NET POCO Entity Framework的REST WCF_第3张图片
Oh,NO~ 直接就挂了。服务端对于 EntityObject 无法序列化成Json格式?

---------------- POCO分界线 ------------------

接下来请出 ADO.NET POCO Entity Generator 进行野猪大改造,剥离一些多余的属性:
1. 切换到 Northwind.edmx 的Model Browser中,右击Model项目:(在edmx视图的空白处右键也可以)
WCF 实例 —— 基于ADO.NET POCO Entity Framework的REST WCF_第4张图片
2. 选择 "ADO.NET POCO Entity Generator" 模板:
WCF 实例 —— 基于ADO.NET POCO Entity Framework的REST WCF_第5张图片
3. 将会有安全提示问是否要在本地生成代码,按下OK后就生成了POCO的代码,并将原来EF Design.cs里的原来的代码都删除了。
WCF 实例 —— 基于ADO.NET POCO Entity Framework的REST WCF_第6张图片
WCF 实例 —— 基于ADO.NET POCO Entity Framework的REST WCF_第7张图片
改造后的EntityObject,属性变成只有 get; set;, Navigation Property 也由EntityCollection<T>变为ICollection<T>:
WCF 实例 —— 基于ADO.NET POCO Entity Framework的REST WCF_第8张图片
再次运行,可以和未使用POCO类型的返回结果比较下看看是不是清爽了很多?
WCF 实例 —— 基于ADO.NET POCO Entity Framework的REST WCF_第9张图片

现在再来看看修改为 Json 格式,OK这次没问题了。
WCF 实例 —— 基于ADO.NET POCO Entity Framework的REST WCF_第10张图片

话说回来既然连 ObjectContext 也是用 T4 重新生成的,那么下面两句代码也通过 T4 生成就不用每个服务方法里都去设定了。

db.ContextOptions.LazyLoadingEnabled = false;

db.ContextOptions.ProxyCreationEnabled = false;


查看 Northwind.context.tt 的代码,在最后可以看到下面的代码:
private void WriteLazyLoadingEnabled(EntityContainer container)
{
   string lazyLoadingAttributeValue = null;
   string lazyLoadingAttributeName = MetadataConstants.EDM_ANNOTATION_09_02 + ":LazyLoadingEnabled";
   if(MetadataTools.TryGetStringMetadataPropertySetting(container, lazyLoadingAttributeName, out lazyLoadingAttributeValue))
   {
       bool isLazyLoading = false;
       if(bool.TryParse(lazyLoadingAttributeValue, out isLazyLoading))
       {
#>
        this.ContextOptions.LazyLoadingEnabled = <#=isLazyLoading.ToString().ToLowerInvariant()#>;
<#+
       }
   }
}
#>

把上面第11行:
this.ContextOptions.LazyLoadingEnabled = <#=isLazyLoading.ToString().ToLowerInvariant()#>
修改为:
this.ContextOptions.LazyLoadingEnabled = false;
this.ContextOptions.ProxyCreationEnabled = false;
生成的ObjectContext的构造函数中就会添加上面的两句代码,所有服务方法就不用设定上面属性了。
public NorthwindEntities()
    : base(ConnectionString, ContainerName)
{
    this.ContextOptions.LazyLoadingEnabled = false;
    this.ContextOptions.ProxyCreationEnabled = false;
}

使用 ADO.NET POCO Entity Generator 进行改造的EF,使得我们可以在服务端可以使用Linq2EF的ORM良好支持,又使得客户端不必为复杂的数据格式而烦恼,是在REST WCF应用中的一大利器。



你可能感兴趣的:(String,REST,application,generator,LINQ,WCF)