Entity Framework4.0 (九EF4与WCF Data Service的结合使用(转)

前面我们讲述了EF4的数据绑定。知道EF4的容器可以作为数据源控件的数据源。 以前我们作数据绑定是指向Dataset,使用DataAdapter与数据库连接,然后fill到dataset中。当我们使用EF4的数据绑定时,我 们的数据源控件不再依靠DataAdapter直接与数据库交互,而是依靠EF4容器,然后再由EF4与数据库交互。

这一次我们讲述:EF4与WCF Data Servicer的结合使用:EF4容器作为Data Service的数据提供者。

如果你对WCF Data Service不了解,没关系。这和Web Service很相像。如果你对Web Service也不了解,也没关系。咱们先把程序跑起来,你看看有多简单就知道是咋回事了。(其实,好多人刚开始接触新事物的时候,一股脑儿找到的资料全是定义。任何一个物事都不是语言文字可以准备定义的。就算定义准确了,能保证读者也能理解准确吗?所以,最简单的方式就是演示出来,让大家看看。就OK了。如果想深入研究,也至少知道努力的方向了。这就是所谓的:"先主杆,后枝叶"的学习过程)呵呵。

好了,不再废话了,大家肯定都烦俺絮叨了。呵呵,

==================================================================

1.启动Visual Studio2010 :File-->new Project-->ASP.NET Web Application. 项目名称:EFWCFDemo。

2.删除项目中使用不到的文件夹和文件(防止它们在这里混淆视听):如下图:

3.在项目EFWCFDemo上面右键—》Add-->New Item .选择ADO.NET Entity Data Modell 名称:Northwind.如下图:

4.在项目EFWCFDemo上面右键—》AddàNew Item. 选择 WCF Data Service:名称:EFWCFService。如下图:

 

5. 添加完以后,会默认打开EFWCFService.svc.cs文件。如果没有打开,你可以双击EFWCFService.svc即可打开EFWCFService.svc.cs文件。有如下代码:

 1 public class EFWCFService : DataService< /* TODO: put your data source class name here */ >
 2      {
 3          // This method is called only once to initialize service-wide policies.
 4          public static void InitializeService(DataServiceConfiguration config)
 5          {
 6              // TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc.
 7  // Examples:
 8  // config.SetEntitySetAccessRule("MyEntityset", EntitySetRights.AllRead);
 9  // config.SetServiceOperationAccessRule("MyServiceOperation", ServiceOperationRights.All);
10  
11  
12              config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
13          }
14      }

更改成下面的代码:(我们就是指定了类EFWCFService的父类的泛型类型为NorthwindEntities。

NorthwindEntities其实就是EF4的容器类了,所以把容器当作泛型参数的实参传进去,Data Service就到该容器中取数据了。为了方便起见,我们把*.edmx和EFWCFService.svc文件放在了同一个项目的同一个 namespace下面。你也可以根据实际需要把它们分开。使用的时候,再把相应的namespace添加进去就行了。)

同时我们也在代码中添加了一行:  config.SetEntitySetAccessRule("*",EntitySetRights.All); 这是配置对EF4容器中的EntitySet的访问权限。第一个参数:“*”代表全部。因为我们只有一个实体集CategorySet。所以一会在浏览器 中我们只会看到一个Categories。第二个参数:EntitySetRights.All指拥有全部的权限。EntitySetRights枚举值 比较简单:见名知意,所以不多讲了。

EFWCFService
  public class EFWCFService : DataService< NorthwindEntities >
     {
         // 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("MyEntityset", EntitySetRights.AllRead);
 // config.SetServiceOperationAccessRule("MyServiceOperation", ServiceOperationRights.All);
 
             config.SetEntitySetAccessRule("*",EntitySetRights.All);
             config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
         }
     }

浏览器显示如下:

1 <?xml version="1.0" encoding="utf-8" standalone="yes" ?> 
2  - <service xml:base="http://localhost:1713/EFWCFService.svc/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:app="http://www.w3.org/2007/app" xmlns="http://www.w3.org/2007/app">
3  - <workspace>
4    <atom:title>Default</atom:title> 
5  - <collection href="Categories">
6    <atom:title>Categories</atom:title> 
7    </collection>
8    </workspace>
9    </service>

说明:第5行:href 的值为当前实体集相对于WCF Data Service项目的URi:即在http://localhost:1713/EFWCFService.svc/的后面再追加:Categories就是当前实体集的URi,你可以试下:如果有类似于“您正在查看的源包含频繁更新的内容。订阅源后,该源会添加到“常见源列表”中。该源的更新信息会自动下载到计算机,通过 Internet Explorer 及其他程序可以查看这些信息”的提示。你可以在浏览器上:工具-》internet选项-如下图:

然后,你再访问CategorySet的URi就ok了。

6.在解决方案上面:右键-》Add -》New Item 选择Windows Form Application。名称:EFWCFTest。

在EFWCFTest项目下面的的References节点上右键,然后添加web service如下图:

在窗体Form1上面添加两个按钮:一个Button(名称:btnFill。显示文本:Fill)和一个ListBox(名称:lboxCategory)如下图:

给btnFill添加Click事件:代码如下:

View Code
 1 View Code 
 2  using System;
 3  using System.Collections.Generic;
 4  using System.ComponentModel;
 5  using System.Data;
 6  using System.Drawing;
 7  using System.Linq;
 8  using System.Text;
 9  using System.Windows.Forms;
10  using EFWCFTest.EFWCFReference;
11  
12  namespace EFWCFTest
13  {
14      public partial class Form1 : Form
15      {
16          public Form1()
17          {
18              InitializeComponent();
19          }
20  
21          private void btnFill_Click(object sender, EventArgs e)
22          {
23              NorthwindEntities svc = new NorthwindEntities(new Uri("http://localhost:1713/EFWCFService.svc/"));
24              foreach (Category c in svc.Categories)
25              {
26                  this.lboxCategory.Items.Add(string.Format("{0}::{1}",c.CategoryID,c.CategoryName));
27              }
28          }
29      }
30  }

注意:

代码第9行:添加了一个命名空间:该命名空间是由添加Web 引用的时候生成的,代表的是本地代理类的命名空间。我们是通过直接操作本地代理,然后由本地代理去查找、访问wcf data service所公开的方法的。

代码第22行,此时的NorthwindEntities已经不再是EF4中的NorthwindEntities了。因为我们在窗体项目中未引用 EF4,我们只是添加了一个Web 引用,指向了WCF Data Service的URi。由WCF Data Service去EF4中找到数据。那代码第22行,此时的NorthwindEntities来自哪呢?你可以在VS2010中定位到该类,然后发现: 它只是一个本地代理类。并不是EF4中,由*.edmx所映射成的类。只是碰巧它们的名字默认是一样的。(不要混淆了哟!!) 

设置EFWCFTest为启动项目,然后运行程序。

点击Fill按钮。如下图:

如果你想像以前使用EF4容器那样使用LINQ 去查询代理时,也可以用以下代码实现:btnFill的click事件。(这里假设我们需要找到CategoryName以“B”开头的实体)

 1 private void btnFill_Click(object sender, EventArgs e)
 2          {
 3              NorthwindEntities svc = new NorthwindEntities(new Uri("http://localhost:1713/EFWCFService.svc/"));
 4  
 5              var categories = from c in svc.Categories
 6                               where c.CategoryName.StartsWith("B")
 7                               select new { c.CategoryID, c.CategoryName };
 8  
 9              foreach (var c in categories)
10              {
11                  this.lboxCategory.Items.Add(string.Format("{0}::{1}", c.CategoryID, c.CategoryName));
12              }
13  
14          }

svc.Categories 的返回类型是:DataServiceQuery<T>,而LINQ表达式筛选后得到的接口是IQueryable<T>。 DataServiceQuery<T>是实现了IQueryable<T>接口的。

 

怎么样?是不是感觉世界又美好了许多。呵呵。

=============================
好了,就到这了。晚安 to you and to me ...

posted on 2012-11-22 00:45  davidkam  阅读(257)  评论(0编辑  收藏  举报