這個Demo的場景說明:
一家酒店將房間信息存儲在SQL Server數據庫中,酒店的工作人員根據客戶的要求的房間類型,查詢出房間的價格,告訴用戶價格,決 定是否訂房。
分布式訂房系統系統設計圖:
上圖說明:
1、通過ADO.NET Data Serivce訪問數據庫,它使用ADO.NET Entity DataModel和WCF Data Service構建一個數據庫增刪查改的WCF服務 。
2、WF4.0 Service是WF4.0的WCF服務,通過WCF訪問ADO.NET Data Serivce。
3、WF4.0 Client和.NET Windows client是兩個客戶端,他們的功能是相同的,通過Internet訪問WF4.0 Service。
傳統的分布式設計圖:
比較一下兩張圖片,你會發現:
1、傳統的數據庫訪問是使用SQL Helper。
2、將業務邏輯宿主在Web Service中,現在是宿主在WF4.0和WCF結合的服務中。
實現:下面我將一步一步實現這個Demo
1、創建數據庫,就一張表如下圖:
2、創建ADO.NET Data Service:
新建一個RentRoom空項目,添加一個ASP.Net應用程序RentRoomDataService,刪除所有的aspx和cs文件。添加一個ADO.NET Entity DataModel項目,將其命名為myModel.edmx。如下圖:
選擇Generates from database,點下一步,新建一個連接字符串,如下圖:
點擊OK,點擊next,選擇表Room,點擊完成,如下圖:
在RentRoomDataService中添加一個WCF Data Service,命名為MyWcfDataService.svc,如下圖:
修改MyWcfDataService.svc.cs代碼:
1 public class MyWcfDataService : DataService<RentRoomEntities2>
2 {
3 // This method is called only once to initialize service-wide policies.
4 public static void InitializeService(DataServiceConfiguration config)
5 {
6 config.SetEntitySetAccessRule("*", EntitySetRights.All);
7 config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);
8 }
9 }
這樣ADO.NET Data Service創建完成。
3、創建RentRoomCustomActivities,它包括三個自定義活動:
先添加MyWcfDataService服務引用,如下圖:
GetInput用於接收等待用戶輸入,代碼如下:
1 public class GetInput : CodeActivity
2 {
3 OutArgument<string> data;
4 public OutArgument<string> Data
5 {
6 get { return data; }
7 set { data = value; }
8 }
9
10 protected override void Execute(CodeActivityContext context)
11 {
12 string input = Console.ReadLine();
13 context.SetValue(data, input);
14 }
15 }
CheckPrice用於查詢房間的價格,調用ADO.NET Data Service,代碼如下:
1 public class CheckPrice : CodeActivity
2 {
3 InArgument<string> roomID;
4 public InArgument<string> RoomID
5 {
6 get { return roomID; }
7 set { roomID = value; }
8 }
9
10 OutArgument<decimal> roomPrice;
11 public OutArgument<decimal> RoomPrice
12 {
13 get { return roomPrice; }
14 set { roomPrice = value; }
15 }
16
17 protected override void Execute(CodeActivityContext context)
18 {
19 string carId = RoomID.Get(context);
20
21 String urlstr = "http://localhost:40438/MyWcfDataService.svc";
22 CarRentalReference.RentRoomEntities2 proxy = new CarRentalReference.RentRoomEntities2(new Uri(urlstr));
23
24 var query = (from c in proxy.Room
25 where c.RoomID == carId
26 select c).First();
27
28 decimal? price = query.RoomPrice;
29
30 context.SetValue(RoomPrice, price);
31 }
32
33
34 }
BookRoom用於確定訂房,調用ADO.NET Data Service,代碼如下:
1 public class BookRoom : CodeActivity
2 {
3 InArgument<string> roomId;
4 public InArgument<string> RoomId
5 {
6 get { return roomId; }
7 set { roomId = value; }
8 }
9
10 protected override void Execute(CodeActivityContext context)
11 {
12 string carId = RoomId.Get(context);
13
14 String urlstr = "http://localhost:40438/MyWcfDataService.svc";
15 CarRentalReference.RentRoomEntities2 proxy = new CarRentalReference.RentRoomEntities2(new Uri(urlstr));
16
17 var query = (from c in proxy.Room
18 where c.RoomID == carId
19 select c);
20
21 foreach (CarRentalReference.Room room in query)
22 {
23 room.Quantity = room.Quantity - 1;
24 proxy.UpdateObject (room);
25 proxy.SaveChanges();
26 break;
27 }
28
29 }
30
31
32 }
RentRoomCustomActivities創建完成。
4、創建RentRoomWFService。這是設計圖上的WF4.0 Service。
這個服務由兩個ReceiveAndSendReply構成,第一個ReceiveAndSendReply,如下圖:
第二個ReceiveAndSendReply,如下圖:
ReceiveAndSendReply具體的設置參考:WF4.0實戰(三):WCF服務 、WF4.0 基礎篇 (二十七) WCF Workflow Service 在WCF中使用WF
在Program.cs中寫啟動這個服務的代碼,如下:
1 static void Main(string[] args)
2 {
3 string baseAddress = "http://localhost:8090/RentRoomService";
4
5
6
7 using (WorkflowServiceHost host =
8 new WorkflowServiceHost(new Workflow1(), new Uri (baseAddress)))
9 {
10 host.Description.Behaviors.Add (new
11 ServiceMetadataBehavior() { HttpGetEnabled = true });
12 host.AddDefaultEndpoints();
13
14 host.Open();
15 Console.WriteLine("Rent Room service listening at: " +
16 baseAddress);
17 Console.WriteLine("Press ENTER to exit");
18 Console.ReadLine();
19 host.Close();
20 }
21 }
22 }
這樣RentRoomWFService完成。
5、客戶端RentRoomWidowsClient
啟動RentRoomWFService,在RentRoomWidowsClient添加RentRoomWFService引用,如下圖:
使用下面代碼模擬訂房:
1 ServiceReference1.RentRoomDataContract contract = new ServiceReference1.RentRoomDataContract();
2 contract.RoomId = "gaoji";
3 contract.CustomerId = "012";
4 ServiceReference1.ServiceClient proxy = new ServiceReference1.ServiceClient();
5 decimal? test = proxy.CheckPrice(contract);
6 bool? test1 = proxy.BookRoom("012");
6、客戶端RentRoomWFClient
定義一個工作流調用WF服務,詳見RentRoomWFClient.Workflow1.xaml。
啟動RentRoomWFService服務,如下圖:
運行效果圖:
代碼:http://files.cnblogs.com/zhuqil/RentRoomWFClient.rar
數據庫:http://files.cnblogs.com/zhuqil/db.rar