代码改变世界

演练二:添加查询方法(MSDN译文)

2010-01-10 19:40  张智清  阅读(569)  评论(0编辑  收藏  举报

上一节的演练仅仅是揭示了创建一个项目通过Domain Service来检索数据的基本步骤而已,未加深入学习如何建立更多复杂的查询方法,诸如接收一个参数请求来筛选数据。

做些查询一个数据源的方法被命名为查询方法。在WCF RIA Services中,查询方法必须以被定义的方式让架构认可这些方法。此外,总是返回一个单一实体的查询与潜在返回一个实体以上的查询是被不同定义的。有关合法查询方法的签名的更多信息,可看Domain Services

当你在Add New Domain Service Class对话框中建立一个新的domain service类并且指定一个实体时,RIA Services架构为由这个服务暴露的每个实体自动创建一个简单的查询方法。这个简单的查询方法检索这个实体所有的记录。而这一章演练阐述了如何添加一个新的查询方法来执行更复杂的类似通过一个参数值来进行筛选的情景,以下是如何添加返回单一实体和返回一个实体集的查询。

添加一个查询方法,它接收一个参数并返回一个单一实体

  1. 打开之前的RIAServicesExample解决方案。
  2. 在服务端项目中,打开那暴露Customer表数据的domain services类,前一讲中此类已命名为CustomerDomainService
  3. 添加一个查询方法,其接受一个整型参数并返回匹配customer ID的Customer实体。
    如果返回单一实体的查询方法包含QueryAttribute属性,则必须设置IsComposable特性为false。用户不能从客户端指定其他查询操作。如果查询方法与查询的预期签名相匹配,你不得不应用QueryAttribute属性。返回值必须是一个实体对象的单一实例。
    [Query(IsComposable=false)]
    public Customer GetCustomersByID(int customerID)
    {
    return this.ObjectContext.Customers.SingleOrDefault(c=>c.CustomerID==customerID);
    }

添加一个查询方法,它接收一个参数并返回一个实体集

这次我们在domain service类中添加的这个查询方法,接受一个字符串参数并返回以字母姓氏开头至结尾名字的任何customers记录。这个方法能够返回一个IQueryable<>对象,因为用户可能需要从客户端提供额外的查询操作。
public IQueryable&lt;Customer&gt; GetCustomersByLastNameLetter(string
startingLastNameLetter)<BR>{<BR>return
this.ObjectContext.Customers.Where(c=&gt;c.LastName.StartsWith(startingLastNameLetter)==true);<BR>}

在客户端项目中这些查询方法的显示结果

MainPage.xaml

<UserControl xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data" 
    x:Class="RIAServicesExample.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.ColumnDefinitions>
            <ColumnDefinition></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="25"></RowDefinition>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>
        <StackPanel Orientation="Horizontal" Grid.Row="0" Grid.Column="0">
            <TextBlock Text="search by id: " ></TextBlock>
            <TextBox Name="IDValue" Width="50" ></TextBox>
            <Button Name="IDButton" Click="IDButton_Click" Content="Submit"></Button>
        </StackPanel>
        <StackPanel Orientation="Horizontal" Grid.Row="0" Grid.Column="1">
            <TextBlock Text="search by name: "></TextBlock>
            <TextBox Name="LetterValue" Width="30"></TextBox>
            <Button Name="LetterButton" Click="LetterButton_Click" Content="Submit"></Button>
        </StackPanel>

      <data:DataGrid Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" Name="CustomerGrid"></data:DataGrid>
    </Grid>
</UserControl>

MainPage.xaml.cs

public partial class MainPage : UserControl
{
    private CustomerDomainContext _customerContext = new CustomerDomainContext();

    public MainPage()
    {
        InitializeComponent();
    }

    private void LetterButton_Click(object sender, RoutedEventArgs e)
    {
        IDButton.IsEnabled = false;
        LetterButton.IsEnabled = false;
        LoadOperation<Customer> loadOp = this._customerContext.Load(this._customerContext.GetCustomersByLastNameLetterQuery(LetterValue.Text), CustomerLoadedCallback, null);
        CustomerGrid.ItemsSource = loadOp.Entities;
    }

    private void IDButton_Click(object sender, RoutedEventArgs e)
    {
        IDButton.IsEnabled = false;
        LetterButton.IsEnabled = false;
        LoadOperation<Customer> loadOp = this._customerContext.Load(this._customerContext.GetCustomersByIDQuery(int.Parse(IDValue.Text)), CustomerLoadedCallback, null);
        CustomerGrid.ItemsSource = loadOp.Entities;
    }

    void CustomerLoadedCallback(LoadOperation<Customer> loadOperation)
    {
        IDButton.IsEnabled = true;
        LetterButton.IsEnabled = true;
    }

}

最后运行这个编译后的应用程序。