• WCF RIA Services 快速上手


    WCF RIA Services 简化开发RIA n-tier 解决方案。让你快速构建Silverlight n-tier应用程序客户端与服务端的通信。下面我们来看一张图:

    IC357993

    下面我们来构建一个简单的DEMO:

    首先,下载Silverlight 4 Tools for Visual Studio 2010 ,建一个Silverlight project:

    Create Silverlight Project in VS2010

    接下弹出对话框,记得Enable WCF RIA Services:

    VS2010 Enable WCF RIA Services

    建立DEMO的表,并插入几条数据:

       1:  CREATE TABLE [dbo].[tblItem](
       2:      [ItemNumber] INT NOT NULL,
       3:      [ItemDescription] [varchar](50) NULL,
       4:      [Quantity] [int] NULL
       5:  CONSTRAINT [PK_tblItem] PRIMARY KEY CLUSTERED 
       6:  (
       7:      [ItemNumber] ASC )
       8:  )
       9:   
      10:  INSERT INTO [tblItem]
      11:             ([ItemNumber]
      12:             ,[ItemDescription]
      13:             ,[Quantity])
      14:  VALUES ('1','Item Name1',1),
      15:         ('2','Item Name2',2),
      16:         ('3','Item Name3',3),              
      17:         ('4','Item Name4',4),
      18:         ('5','Item Name5',5),
      19:         ('6','Item Name6',6)

    接着我们对这个TABLE建EF4 DATA MODEL,这里我们将不再深入,待建立好后,创建DomainService:

    Create Domain Serivce

    然后选择那个Entities:

    Domain Service - New Domain Service Class

    接下将会生成一个Service的文件:

       1:  namespace RIAServices.Web
       2:  {
       3:      using System;
       4:      using System.Collections.Generic;
       5:      using System.ComponentModel;
       6:      using System.ComponentModel.DataAnnotations;
       7:      using System.Data;
       8:      using System.Linq;
       9:      using System.ServiceModel.DomainServices.EntityFramework;
      10:      using System.ServiceModel.DomainServices.Hosting;
      11:      using System.ServiceModel.DomainServices.Server;
      12:   
      13:   
      14:      // Implements application logic using the BirdLLEntities context.
      15:      // TODO: Add your application logic to these methods or in additional methods.
      16:      // TODO: Wire up authentication (Windows/ASP.NET Forms) and uncomment the following to disable anonymous access
      17:      // Also consider adding roles to restrict access as appropriate.
      18:      // [RequiresAuthentication]
      19:      [EnableClientAccess()]
      20:      public class ItemService : LinqToEntitiesDomainService<BirdLLEntities>
      21:      {
      22:   
      23:          // TODO:
      24:          // Consider constraining the results of your query method.  If you need additional input you can
      25:          // add parameters to this method or create additional query methods with different names.
      26:          // To support paging you will need to add ordering to the 'tblItems' query.
      27:          public IQueryable<tblItem> GetTblItems()
      28:          {
      29:              return this.ObjectContext.tblItems;
      30:          }
      31:   
      32:          public void InsertTblItem(tblItem tblItem)
      33:          {
      34:              if ((tblItem.EntityState != EntityState.Detached))
      35:              {
      36:                  this.ObjectContext.ObjectStateManager.ChangeObjectState(tblItem, EntityState.Added);
      37:              }
      38:              else
      39:              {
      40:                  this.ObjectContext.tblItems.AddObject(tblItem);
      41:              }
      42:          }
      43:   
      44:          public void UpdateTblItem(tblItem currenttblItem)
      45:          {
      46:              this.ObjectContext.tblItems.AttachAsModified(currenttblItem, this.ChangeSet.GetOriginal(currenttblItem));
      47:          }
      48:   
      49:          public void DeleteTblItem(tblItem tblItem)
      50:          {
      51:              if ((tblItem.EntityState == EntityState.Detached))
      52:              {
      53:                  this.ObjectContext.tblItems.Attach(tblItem);
      54:              }
      55:              this.ObjectContext.tblItems.DeleteObject(tblItem);
      56:          }
      57:   
      58:          /// <summary>
      59:          /// Gets the TBL items by item number.
      60:          /// </summary>
      61:          /// <param name="itemnumber">The itemnumber.</param>
      62:          /// <returns></returns>
      63:          public IQueryable<tblItem> GetTblItemsByItemNumber(int itemnumber)
      64:          {
      65:              return this.ObjectContext.tblItems.Where(i => i.ItemNumber == itemnumber);
      66:          }
      67:      }

    另一个是Metadata :

       1:  namespace RIAServices.Web
       2:  {
       3:      using System;
       4:      using System.Collections.Generic;
       5:      using System.ComponentModel;
       6:      using System.ComponentModel.DataAnnotations;
       7:      using System.Linq;
       8:      using System.ServiceModel.DomainServices.Hosting;
       9:      using System.ServiceModel.DomainServices.Server;
      10:   
      11:      // The MetadataTypeAttribute identifies tblItemMetadata as the class
      12:      // that carries additional metadata for the tblItem class.
      13:      [MetadataTypeAttribute(typeof(tblItem.tblItemMetadata))]
      14:      public partial class tblItem
      15:      {
      16:   
      17:          // This class allows you to attach custom attributes to properties
      18:          // of the tblItem class.
      19:          //
      20:          // For example, the following marks the Xyz property as a
      21:          // required property and specifies the format for valid values:
      22:          //    [Required]
      23:          //    [RegularExpression("[A-Z][A-Za-z0-9]*")]
      24:          //    [StringLength(32)]
      25:          //    public string Xyz { get; set; }
      26:          internal sealed class tblItemMetadata
      27:          {
      28:   
      29:              // Metadata classes are not meant to be instantiated.
      30:              private tblItemMetadata()
      31:              {
      32:              }
      33:   
      34:              public string ItemDescription { get; set; }
      35:   
      36:              public int ItemNumber { get; set; }
      37:   
      38:              public Nullable<int> Quantity { get; set; }
      39:          }
      40:      }
      41:  }

    然后打开Data—>Show Data Source,如下图:

    Domain Context

    然后打开另一个Project中Mainpage.xaml,我们之前应用生成这样的XMAL:

       1:  <UserControl x:Class="RIAServices.MainPage"
       2:      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
       3:      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
       4:      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
       5:      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
       6:      mc:Ignorable="d"
       7:      d:DesignHeight="536" d:DesignWidth="463" xmlns:riaControls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.DomainServices" xmlns:my="clr-namespace:RIAServices.Web" xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk">
       8:   
       9:      <Grid x:Name="LayoutRoot" Background="White" Height="536" Width="463">
      10:          <Grid.ColumnDefinitions>
      11:              <ColumnDefinition Width="140*" />
      12:              <ColumnDefinition Width="47*" />
      13:              <ColumnDefinition Width="405*" />
      14:          </Grid.ColumnDefinitions>
      15:          <riaControls:DomainDataSource AutoLoad="False" d:DesignData="{d:DesignInstance my:tblItem, CreateList=true}" Height="0" LoadedData="tblItemDomainDataSource_LoadedData" Name="tblItemDomainDataSource" QueryName="GetTblItemsQuery" Width="0" Margin="0,0,140,393">
      16:              <riaControls:DomainDataSource.DomainContext>
      17:                  <my:ItemContext />
      18:              </riaControls:DomainDataSource.DomainContext>
      19:          </riaControls:DomainDataSource>
      20:          <sdk:DataGrid AutoGenerateColumns="False" Height="181" HorizontalAlignment="Left" ItemsSource="{Binding ElementName=tblItemDomainDataSource, Path=Data}" Name="tblItemDataGrid" RowDetailsVisibilityMode="VisibleWhenSelected" VerticalAlignment="Top" Width="400" Margin="0,58,0,0" Grid.ColumnSpan="3">
      21:              <sdk:DataGrid.Columns>
      22:                  <sdk:DataGridTextColumn x:Name="itemDescriptionColumn" Binding="{Binding Path=ItemDescription}" Header="Item Description" Width="SizeToHeader" />
      23:                  <sdk:DataGridTextColumn x:Name="itemNumberColumn" Binding="{Binding Path=ItemNumber, Mode=OneWay}" Header="Item Number" IsReadOnly="True" Width="SizeToHeader" />
      24:                  <sdk:DataGridTextColumn x:Name="quantityColumn" Binding="{Binding Path=Quantity}" Header="Quantity" Width="SizeToHeader" />
      25:              </sdk:DataGrid.Columns>
      26:          </sdk:DataGrid>
      27:          <Button Content="Query" Height="23" HorizontalAlignment="Left" Margin="171,12,0,0" Name="btnquery" VerticalAlignment="Top" Width="75" Click="btnquery_Click" Grid.Column="2" />
      28:          <TextBox Height="23" HorizontalAlignment="Left" Margin="1,12,0,0" Name="txtItemNumber" VerticalAlignment="Top" Width="120" Grid.ColumnSpan="2" />
      29:          <sdk:DataGrid AutoGenerateColumns="False" Height="179" HorizontalAlignment="Left" ItemsSource="{Binding ElementName=tblItemDomainDataSource, Path=Data}" Margin="1,320,0,0" Name="dataGrid1" RowDetailsVisibilityMode="VisibleWhenSelected" VerticalAlignment="Top" Width="400" Grid.ColumnSpan="3">
      30:              <sdk:DataGrid.Columns>
      31:                  <sdk:DataGridTextColumn x:Name="dataGridTextColumn1" Binding="{Binding Path=ItemDescription}" Header="Item Description" Width="SizeToHeader" />
      32:                  <sdk:DataGridTextColumn x:Name="dataGridTextColumn2" Binding="{Binding Path=ItemNumber, Mode=OneWay}" Header="Item Number" IsReadOnly="True" Width="SizeToHeader" />
      33:                  <sdk:DataGridTextColumn x:Name="dataGridTextColumn3" Binding="{Binding Path=Quantity}" Header="Quantity" Width="SizeToHeader" />
      34:              </sdk:DataGrid.Columns>
      35:          </sdk:DataGrid>
      36:          <sdk:Label Grid.ColumnSpan="3" Height="21" HorizontalAlignment="Left" Margin="1,281,0,0" Name="label1" VerticalAlignment="Top" Width="189" Content="CustomerService from ADO.NET" />
      37:      </Grid>
      38:  </UserControl>

    为了对比我们建立另一个自定义DomainService, 也需要建立一个Entity:

       1:  using System;
       2:  using System.Collections.Generic;
       3:  using System.ComponentModel;
       4:  using System.ComponentModel.DataAnnotations;
       5:  using System.Linq;
       6:  using System.ServiceModel.DomainServices.Hosting;
       7:  using System.ServiceModel.DomainServices.Server;
       8:   
       9:  namespace RIAServices.Web
      10:  {
      11:      public class Item
      12:      {
      13:          [Key]
      14:          public int ItemNumber { get; set; }
      15:          public string ItemDescription { get; set; }
      16:          public Nullable<int> Quantity { get; set; }
      17:      }
      18:  }

    CustomerDomainService,里面我们使用原生态的ADO.NET进行数据访问,你也可以替代成你自己的数据Provider.

       1:      [EnableClientAccess()]
       2:      public class CustomerDomainService : DomainService
       3:      {
       4:          public List<Item> GetItemsFromDatabase()
       5:          {
       6:              SqlConnection sqlConnection = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["MainDb"].ToString());
       7:              DataSet objSet = new DataSet();
       8:              SqlCommand sqlCommand = new SqlCommand();
       9:              sqlCommand.Connection = sqlConnection;
      10:              sqlCommand.CommandText = "Select * FROM tblItem";
      11:              SqlDataAdapter sqlDataAdapter = new SqlDataAdapter();
      12:              sqlDataAdapter.SelectCommand = sqlCommand;
      13:              sqlDataAdapter.Fill(objSet);
      14:   
      15:              List<Item> lstResult = new List<Item>();
      16:              Item objEmployee;
      17:   
      18:              if (objSet.Tables.Count > 0)
      19:              {
      20:                  foreach (DataRow dr in objSet.Tables[0].Rows)
      21:                  {
      22:                      objEmployee = new Item();
      23:                      objEmployee.Quantity = Convert.ToInt32(dr["Quantity"]);
      24:                      objEmployee.ItemDescription = dr["ItemDescription"].ToString();
      25:                      objEmployee.ItemNumber = Convert.ToInt32(dr["ItemNumber"]);
      26:                      lstResult.Add(objEmployee);
      27:                  }
      28:              }
      29:              return lstResult;
      30:          }
      31:      }

    最后我们来看MainPage.xaml.cs 的代码:

       1:     public partial class MainPage : UserControl
       2:      {
       3:          public MainPage()
       4:          {
       5:              InitializeComponent();
       6:   
       7:              var itemContext = new ItemContext();
       8:              tblItemDataGrid.ItemsSource = itemContext.tblItems;
       9:              EntityQuery<tblItem> s = itemContext.GetTblItemsQuery();
      10:              LoadOperation<tblItem> op = itemContext.Load(s);
      11:   
      12:              //Use another domain service
      13:              var customerservice = new CustomerDomainContext();
      14:              dataGrid1.ItemsSource = customerservice.Items;
      15:              EntityQuery<Item> s2 = customerservice.GetItemsFromDatabaseQuery();
      16:              LoadOperation<Item> op2 = customerservice.Load(s2);
      17:   
      18:          }
      19:   
      20:          private void tblItemDomainDataSource_LoadedData(object sender, System.Windows.Controls.LoadedDataEventArgs e)
      21:          {
      22:              if (e.HasError)
      23:              {
      24:                  System.Windows.MessageBox.Show(e.Error.ToString(), "Load Error", System.Windows.MessageBoxButton.OK);
      25:                  e.MarkErrorAsHandled();
      26:              }
      27:          }
      28:   
      29:          /// <summary>
      30:          /// Handles the Click event of the btnquery control.
      31:          /// </summary>
      32:          /// <param name="sender">The source of the event.</param>
      33:          /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
      34:          private void btnquery_Click(object sender, RoutedEventArgs e)
      35:          {
      36:              var tt = new ItemContext();
      37:              tblItemDataGrid.ItemsSource = tt.tblItems;
      38:              EntityQuery<tblItem> s = tt.GetTblItemsByItemNumberQuery(txtItemNumber.Text == "" ? 0 : Convert.ToInt32(txtItemNumber.Text));
      39:              LoadOperation<tblItem> op = tt.Load(s);
      40:          }
      41:   
      42:      }

    这里我们禁用了默认SilverLight DataGrid的自动绑定,在InitializeComponent方法后增加了代码绑定。btnquery_Click方法对应的是UI上那个Button的Click事件,用来做数据查询。
    另一个要注意是ItemService中的GetTblItemsByItemNumber方法是后面加入的,其它方法是自动生成的。最后F5运动后效果是:

    image

    简单查询的结果:

    image

    这个后面访问了WCF Service地址是:

    http://localhost:54934/Services/RIAServices-Web-ItemService.svc

    通过Monitor我们看到GetItemsFromDatabase方法返回的数据是:

    @GetItemsFromDatabaseResponsehttp://tempuri.org/@GetItemsFromDatabaseResult    aDomainServices    i)http://www.w3.org/2001/XMLSchema-instance^
    TotalCount?^ RootResults    b7http://schemas.datacontract.org/2004/07/RIAServices.Web_Item_ItemDescription?Item Name1_
    ItemNumber僟Quantity?_Item_ItemDescription?Item Name2_
    ItemNumber?_Quantity?_Item_ItemDescription?Item Name3_
    ItemNumber?_Quantity?_Item_ItemDescription?Item Name4_
    ItemNumber?_Quantity?_Item_ItemDescription?Item Name5_
    ItemNumber?_Quantity?_Item_ItemDescription?Item Name6_
    ItemNumber?_Quantity?

    这是WCF RIA Service默认的数据格式。有时间将在以后解析它们。希望对您的开发有帮助。


    作者:Petter Liu
    出处:http://www.cnblogs.com/wintersun/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
    该文章也同时发布在我的独立博客中-Petter Liu Blog

  • 相关阅读:
    8种Nosql数据库系统对比
    How to get the value of a form element : check box and radio button
    Jquery 操作Html 控件 CheckBox、Radio、Select 控件
    Reading CheckBoxes and Radio Buttons
    java中的匿名内部类总结
    如何理解java泛型类
    java 多态
    linux下使用 du查看某个文件或目录占用磁盘空间的大小
    内网ip范围
    Nginx配置优化参考
  • 原文地址:https://www.cnblogs.com/wintersun/p/1857731.html
Copyright © 2020-2023  润新知