演练:编辑域服务中的数据

在本演练中,您将了解如何创建一个界面,该界面使用户能够更改显示的数据并且在数据库中保存这些更改。

当您在域服务中添加了更新、插入或删除方法后,可以在 Silverlight 客户端中创建一个界面,以便用户能够更改数据。所有更改都在 EntityChangeSet 对象中跟踪,并且这些更改在您调用 SubmitChanges 方法时一起提交。

必备条件

除 WCF RIA Services 和 WCF RIA Services 工具包之外,本演练和 WCF RIA Services 文档中提供的其他演练还要求正确安装和配置 Visual Studio 2010 和 Silverlight Developer 运行时及 SDK 等必备程序。它们还要求安装和配置具有高级服务的 SQL Server 2008 R2 Express 以及安装 AdventureWorks OLTP 和 LT 数据库。

WCF RIA Services 的必备条件节点中的主题提供有关如何满足这些前提条件的详细说明。在继续本演练之前,请按照此处提供的说明执行操作,以确保您在执行本 RIA Services 演练时尽可能少地遇到问题。

本演练假定您已完成演练:创建 RIA Services 解决方案,并从通过此处描述的过程创建的应用程序继续。

显示和编辑域服务中的数据

  1. 打开来自演练:创建 RIA Services 解决方案的 RIAServicesExample 解决方案。

  2. 在 MainPage.xaml 中,更改界面以使用户能够保存或拒绝 DataGrid 中的更改。

    下面的 XAML 添加一个**“Save Changes”按钮、一个“Reject Changes”**按钮和一个文本块。

    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.RowDefinitions>
            <RowDefinition Height="40"></RowDefinition>
            <RowDefinition Height="*"></RowDefinition>
        </Grid.RowDefinitions>
        <StackPanel HorizontalAlignment="Center" Grid.Row="0" Orientation="Horizontal">
            <Button Content="Save Changes" Click="SaveButton_Click" Margin="5" x:Name="SaveButton"></Button>
            <Button Content="Reject Changes" Click="RejectButton_Click" Margin="5" x:Name="RejectButton"></Button>
            <TextBlock x:Name="ChangeText" VerticalAlignment="Center" Width="Auto"></TextBlock>
        </StackPanel>
        <data:DataGrid Grid.Row="1" Name="CustomerGrid" RowEditEnded="CustomerGrid_RowEditEnded"></data:DataGrid>
    </Grid>
    
  3. 在 MainPage.xaml 的代码隐藏页中,为按钮单击事件添加多个事件处理程序,为 RowEditEnded 事件添加一个事件处理程序,添加一个名为 OnSubmitCompleted 的回调方法,并且添加一个用于评估挂起的更改的方法。

    Private Sub SaveButton_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
        _customerContext.SubmitChanges(AddressOf OnSubmitCompleted, Nothing)
    End Sub
    
    Private Sub RejectButton_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
        _customerContext.RejectChanges()
        CheckChanges()
    End Sub
    
    Private Sub CustomerGrid_RowEditEnded(ByVal sender As System.Object, ByVal e As System.Windows.Controls.DataGridRowEditEndedEventArgs)
        CheckChanges()
    End Sub
    
    Private Sub CheckChanges()
        Dim changeSet = _customerContext.EntityContainer.GetChanges()
        ChangeText.Text = changeSet.ToString()
    
        Dim hasChanges = _customerContext.HasChanges
        SaveButton.IsEnabled = hasChanges
        RejectButton.IsEnabled = hasChanges
    End Sub
    
    Private Sub OnSubmitCompleted(ByVal so As SubmitOperation)
        If (so.HasError) Then
            MessageBox.Show(String.Format("Submit Failed: {0}", so.Error.Message))
            so.MarkErrorAsHandled()
        End If
        CheckChanges()
    End Sub
    
    private void SaveButton_Click(object sender, RoutedEventArgs e)
    {
        _customerContext.SubmitChanges(OnSubmitCompleted, null);
    }
    
    private void RejectButton_Click(object sender, RoutedEventArgs e)
    {
        _customerContext.RejectChanges();
        CheckChanges();
    }
    
    private void CustomerGrid_RowEditEnded(object sender, DataGridRowEditEndedEventArgs e)
    {
        CheckChanges();
    }
    
    private void CheckChanges()
    {
        EntityChangeSet changeSet = _customerContext.EntityContainer.GetChanges();
        ChangeText.Text = changeSet.ToString();
    
        bool hasChanges = _customerContext.HasChanges;
        SaveButton.IsEnabled = hasChanges;
        RejectButton.IsEnabled = hasChanges;
    }
    
    private void OnSubmitCompleted(SubmitOperation so)
    {
        if (so.HasError)
        {
            MessageBox.Show(string.Format("Submit Failed: {0}", so.Error.Message));
            so.MarkErrorAsHandled();
        }
        CheckChanges();
    }
    

为要更新的实体设置元数据

  1. 在服务器项目中,打开名为 Customer.metadata.cs 或 Customer.metadata.vb 的元数据类。

    有关更多信息,请参见如何:添加元数据类

  2. 在该元数据类中,将其 AllowEdit 属性设置为 falseEditableAttribute 特性添加到 CustomerIDModifiedDate 属性。

    您将 EditableAttribute 特性应用于某一属性,以便指示该属性是否可供用户在某一客户端应用程序中进行编辑。在您将 AllowEdit 属性设置为 false 时,该属性在客户端应用程序中是只读的。在这个示例中,您将显示 CustomerIDModifiedDate 属性的值,但不希望用户修改这些值。

  3. ExcludeAttribute 特性添加到 rowguid 属性。

    您将 ExcludeAttribute 特性应用到不希望在客户端项目的生成的代码中包括的属性。在这个示例中,没有理由在客户端项目中公开 rowguid 属性。

    下面的代码显示该元数据类的内容。

    <MetadataTypeAttribute(GetType(Customer.CustomerMetadata))>  _
    Partial Public Class Customer
    
        Friend NotInheritable Class CustomerMetadata
    
            'Metadata classes are not meant to be instantiated.
            Private Sub New()
                MyBase.New
            End Sub
    
            <Editable(False)> _
            Public CustomerID As Integer
    
            <Editable(False)> _
            Public ModifiedDate As DateTime
    
            <Exclude()> _
            Public rowguid As Guid
    
    
        End Class
    End Class
    
    [MetadataTypeAttribute(typeof(Customer.CustomerMetadata))]
    public partial class Customer
    {
        internal sealed class CustomerMetadata
        {
    
            // Metadata classes are not meant to be instantiated.
            private CustomerMetadata()
            {
            }
    
            [Editable(false)]
            public int CustomerID;
    
            [Editable(false)]
            public DateTime ModifiedDate;
    
            [Exclude]
            public Guid rowguid;
    
        }
    }
    
  4. 为命名空间添加所需的 usingImports 语句,例如 System.ComponentModel.DataAnnotationsSystem.ServiceModel.DomainServices.Server

  5. 运行 (F5) 该应用程序。

    请注意,您可以编辑 DataGrid 中的值。在您退出已编辑的行时,ChangeText 值将用挂起的更改的说明进行更新。在您单击“Save Changes”按钮时,数据更改将保存在数据库中。在您单击“Reject Changes”按钮时,将还原所有挂起的更改。