DomainDataSource

WCF RIA Services 提供 DomainDataSource 控件,该控件可简化用户界面与域上下文中的数据之间的交互。使用 DomainDataSource 控件,仅使用声明性语法即可检索、编辑数据并确定数据的形状。您需要指定要与 DomainDataSource 一同使用的域上下文,然后调用通过该域上下文提供的操作。

为 DomainDataSource 配置 Silverlight 应用程序

若要使用 DomainDataSource 控件,必须在 Silverlight 项目中添加对 System.Windows.Controls.DomainServices 程序集的引用。在您从工具箱中拖动 DomainDataSource 时,会自动添加此引用。或者,要将 DataGridDomainDataSource 一同使用,您还必须添加对 System.Windows.Controls.Data 的引用。在您从工具箱中拖动 DataGrid 控件时,也会自动添加此引用。

宿主控件(如 UserControl)必须包含以下命名空间引用:

xmlns:riaControls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.DomainServices"

或者,要将 DataGrid 控件与 DomainDataSource 一同使用,还必须添加以下命名空间:

xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"

若要在声明性代码中定义域上下文,则必须包含服务器项目的命名空间。在下面的示例中,ExampleApplication.Web 是服务器项目的名称。您将使用您自己的服务器项目的名称。

xmlns:domain="clr-namespace:ExampleApplication.Web"

检索和显示数据

指定 DomainDataSource 的域上下文,并提供用于加载数据的方法的名称。然后将呈现控件(如 DataGrid)绑定到 DomainDataSource。下面的示例演示一个 DomainDataSource,该控件从名为 ProductDomainContext 的域上下文中检索数据,并在 DataGrid 控件中显示这些数据。只有域服务中存在名为 GetProducts() 的查询方法,此示例才能正常运行。

<UserControl x:Class="ExampleApplication.MainPage"
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="https://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:riaControls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.DomainServices"
    xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"
    xmlns:domain="clr-namespace:ExampleApplication.Web"
    mc:Ignorable="d">

    <Grid x:Name="LayoutRoot" Background="White">
        <riaControls:DomainDataSource Name="source" AutoLoad="True" QueryName="GetProducts">
            <riaControls:DomainDataSource.DomainContext>
                <domain:ProductDomainContext />
            </riaControls:DomainDataSource.DomainContext>
        </riaControls:DomainDataSource>
        <data:DataGrid ItemsSource="{Binding Data, ElementName=source}"  />
    </Grid>
</UserControl>

向查询添加参数

在某些情况下,查询方法需要参数值。通常,查询方法需要通过参数值来筛选返回的数据。DomainDataSource 类提供了 QueryParameters 集合以便于添加参数。下面的示例演示如何使用声明性文本中指定的值来添加参数值。

<Grid x:Name="LayoutRoot" Background="White">
    <riaControls:DomainDataSource Name="source" QueryName="GetProductsByColor" AutoLoad="true">
        <riaControls:DomainDataSource.DomainContext>
            <domain:ProductDomainContext />
        </riaControls:DomainDataSource.DomainContext>
        <riaControls:DomainDataSource.QueryParameters>
            <riaControls:Parameter ParameterName="color" Value="Black" />
        </riaControls:DomainDataSource.QueryParameters>
    </riaControls:DomainDataSource>
    <data:DataGrid ItemsSource="{Binding Data, ElementName=source}" />
</Grid>

您还可以为查询添加使用用户提供的值的参数。您需要将 Parameter 对象绑定到包含要在查询中使用的值的用户输入控件。下面的示例演示如何将 ComboBox 中的值指定为参数值。

<Grid x:Name="LayoutRoot" Background="White">
    <Grid.RowDefinitions>
        <RowDefinition Height="25" />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
    <riaControls:DomainDataSource Name="source" QueryName="GetProductsByColor" AutoLoad="true">
        <riaControls:DomainDataSource.DomainContext>
            <domain:ProductDomainContext />
        </riaControls:DomainDataSource.DomainContext>
        <riaControls:DomainDataSource.QueryParameters>
            <riaControls:Parameter ParameterName="color" Value="{Binding ElementName=colorCombo, Path=SelectedItem.Content}" />
        </riaControls:DomainDataSource.QueryParameters>
    </riaControls:DomainDataSource>
    <ComboBox Width="60"  Grid.Row="0" x:Name="colorCombo">
        <ComboBoxItem Content="Black" />
        <ComboBoxItem Content="Blue" />
    </ComboBox>
    <data:DataGrid Grid.Row="1" ItemsSource="{Binding Data, ElementName=source}" />
</Grid>

排序

DomainDataSource 提供了 SortDescriptors 集合,用来帮助对数据进行排序。在 SortDescriptors 集合中,您可以添加 SortDescriptor 实例,该实例描述用于对集合进行排序的值。可以添加任意多个 SortDescriptor 实例以提供排序层。可以指定是按升序还是降序排序数据。下面的示例演示如何将一个排序描述符添加到 DomainDataSource。从查询中检索的数据按 StandardPrice 属性中的值进行排序。

<Grid x:Name="LayoutRoot" Background="White">
    <riaControls:DomainDataSource Name="source" QueryName="GetProducts" AutoLoad="true">
        <riaControls:DomainDataSource.DomainContext>
            <domain:ProductDomainContext />
        </riaControls:DomainDataSource.DomainContext>
        <riaControls:DomainDataSource.SortDescriptors>
            <riaControls:SortDescriptor PropertyPath="StandardCost" Direction="Ascending" />
            <riaControls:SortDescriptor PropertyPath="ProductID" Direction="Ascending" />
        </riaControls:DomainDataSource.SortDescriptors>
    </riaControls:DomainDataSource>
    <data:DataGrid ItemsSource="{Binding Data, ElementName=source}" />
</Grid>

同时实现分页和排序时,至少包含一个 SortDescriptor,将其 PropertyPath 特性分配给包含唯一值(如主键)的属性。或者,将基于包含唯一值的属性的 OrderBy 子句添加到 DomainDataSource 中的查询。如果仅对不包含唯一值的属性排序数据,返回值可能包含不一致的数据或缺少跨页数据。

分组

DomainDataSource 提供了 GroupDescriptors 集合,帮助按照属性值对数据进行分组。在 GroupDescriptors 集合中,您可以添加 GroupDescriptor 实例,此类实例定义用于分组的值。可以根据需要添加多个 GroupDescriptor 实例。

RIA_GroupedData

下面的示例演示如何添加用于分组的值。

<Grid x:Name="LayoutRoot" Background="White">
    <riaControls:DomainDataSource Name="source" QueryName="GetProducts" AutoLoad="true">
        <riaControls:DomainDataSource.DomainContext>
            <domain:ProductDomainContext />
        </riaControls:DomainDataSource.DomainContext>
        <riaControls:DomainDataSource.GroupDescriptors>
            <riaControls:GroupDescriptor PropertyPath="Size" />
        </riaControls:DomainDataSource.GroupDescriptors>
    </riaControls:DomainDataSource>
    <data:DataGrid ItemsSource="{Binding Data, ElementName=source}" />
</Grid>

筛选

DomainDataSource 控件提供 FilterDescriptors 集合以帮助您筛选查询返回的数据。通过添加筛选器,您可以指定从域上下文加载仅符合筛选器中条件的实体。通过设置 DomainDataSource 对象上的 FilterOperator 属性,定义不同筛选器之间的逻辑关系。FilterOperator 属性支持 FilterDescriptorLogicalOperator 枚举器中的所有值。

FilterDescriptor 实例中,设置 Operator 属性以指定筛选时要使用的比较类型。筛选器描述符支持 FilterOperator 枚举器中的操作。

下面的示例显示两个筛选器描述符,它们通过一个逻辑 AND 语句连接。一个筛选器依赖于用户输入,另一个筛选器则在声明性语法中指定。

<Grid x:Name="LayoutRoot" Background="White">
    <Grid.RowDefinitions>
        <RowDefinition Height="25" />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
    <riaControls:DomainDataSource Name="source" FilterOperator="And" QueryName="GetProducts" AutoLoad="true">
        <riaControls:DomainDataSource.DomainContext>
            <domain:ProductDomainContext />
        </riaControls:DomainDataSource.DomainContext>
        <riaControls:DomainDataSource.FilterDescriptors>
            <riaControls:FilterDescriptor PropertyPath="Color" Operator="IsEqualTo" Value="Blue" />
            <riaControls:FilterDescriptor PropertyPath="ListPrice" Operator="IsLessThanOrEqualTo" Value="{Binding ElementName=MaxPrice, Path=SelectedItem.Content}" />
        </riaControls:DomainDataSource.FilterDescriptors>
    </riaControls:DomainDataSource>
    <ComboBox x:Name="MaxPrice" Grid.Row="0" Width="60" SelectedIndex="0">
        <ComboBoxItem Content="100" />
        <ComboBoxItem Content="500" />
        <ComboBoxItem Content="1000" />
    </ComboBox>
    <data:DataGrid Grid.Row="1" ItemsSource="{Binding Data, ElementName=source}" />
</Grid>

分页

在显示大量实体时,您可能希望在用户界面中提供分页功能。DomainDataSource 控件支持您指定要加载的实体数以及要显示在页面上的实体数。仅当用户导航到包含尚未加载的实体的页面时才加载新记录。通过设置 PageSizeLoadSize 属性来指定用于分页的参数。然后,需要将一个 DataPager 实例绑定到 DomainDataSource 以实现用于分页的界面。

note注意:
如果将应用程序中的 DataPager 与实体框架数据存储区一同使用,则必须对查询返回的数据进行排序,这样 DataPager 才能正常工作。实体框架不支持在查询方法中不存在 OrderBy 子句的情况下对数据分页,也不支持在 Silverlight 客户端上指定的排序。

下面的示例演示如何使用 DomainDataSource 进行分页。

<Grid x:Name="LayoutRoot" Background="White">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
    <riaControls:DomainDataSource PageSize="15" LoadSize="30" Name="source" QueryName="GetProducts" AutoLoad="true">
        <riaControls:DomainDataSource.DomainContext>
            <domain:ProductDomainContext />
        </riaControls:DomainDataSource.DomainContext>
        <riaControls:DomainDataSource.SortDescriptors>
            <riaControls:SortDescriptor PropertyPath="ListPrice" />
        </riaControls:DomainDataSource.SortDescriptors>
    </riaControls:DomainDataSource>
    <data:DataGrid Grid.Row="0" ItemsSource="{Binding Data, ElementName=source}" />
    <data:DataPager Grid.Row="1" Source="{Binding Data, ElementName=source}" />
</Grid>

编辑

若要保留数据修改,请调用 DomainDataSource 对象上的 SubmitChanges 方法。若要取消更改,请调用 RejectChanges 方法。