稳扎稳打Silverlight(57) - 4.0通信之WCF RIA Services: 概述, 通过 DomainDataSource 实现数据的添加、查询、更新和删除操作
稳扎稳打Silverlight(57) - 4.0通信之WCF RIA Services: 概述, 通过 DomainDataSource 实现数据的添加、查询、更新和删除操作
作者:webabcd
介绍
Silverlight 4.0 之 WCF RIA Services:概述以及如何通过 DomainDataSource 实现数据的添加、查询、更新和删除操作,以及服务端的查询、排序和分页等逻辑
在线DEMO
http://www.cnblogs.com/webabcd/archive/2010/08/09/1795417.html
示例
1、概述
Summary.xaml
代码
<navigation:Page x:Class="Silverlight40.WCFRIAServices.Summary"
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"
xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
Title="Summary Page">
<Grid x:Name="LayoutRoot">
<StackPanel HorizontalAlignment="Left">
<StackPanel Orientation="Horizontal">
<Image Source="/WCFRIAServices/1.png" Margin="10" />
<Image Source="/WCFRIAServices/2.png" Margin="10" />
<Image Source="/WCFRIAServices/3.png" Margin="10" />
</StackPanel>
<TextBlock>
<Run>1、WCF RIA Services link - 用于连接中间层和表现层,在 Silverlight 项目的属性中可以设置 WCF RIA Services link</Run>
<LineBreak />
<Run>2、图1:最简单的 WCF RIA Services link;图2:带有类库的 WCF RIA Services link;图3:带有多个 RIA Services 类库的 WCF RIA Services link</Run>
<LineBreak />
<Run>3、在服务端创建 Domain Service Class 用于提供服务,客户端的 Generated_Code 文件夹内会自动生成数据上下文代码</Run>
<LineBreak />
<Run>4、共享代码:中间层按 *.shared.cs 规范保存的代码会 push 到表现层的 Generated_Code 文件夹内;文件链接:添加已存在文件时,选择“Add As Link”,此为 pull 模型</Run>
</TextBlock>
</StackPanel>
</Grid>
</navigation:Page>
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"
xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
Title="Summary Page">
<Grid x:Name="LayoutRoot">
<StackPanel HorizontalAlignment="Left">
<StackPanel Orientation="Horizontal">
<Image Source="/WCFRIAServices/1.png" Margin="10" />
<Image Source="/WCFRIAServices/2.png" Margin="10" />
<Image Source="/WCFRIAServices/3.png" Margin="10" />
</StackPanel>
<TextBlock>
<Run>1、WCF RIA Services link - 用于连接中间层和表现层,在 Silverlight 项目的属性中可以设置 WCF RIA Services link</Run>
<LineBreak />
<Run>2、图1:最简单的 WCF RIA Services link;图2:带有类库的 WCF RIA Services link;图3:带有多个 RIA Services 类库的 WCF RIA Services link</Run>
<LineBreak />
<Run>3、在服务端创建 Domain Service Class 用于提供服务,客户端的 Generated_Code 文件夹内会自动生成数据上下文代码</Run>
<LineBreak />
<Run>4、共享代码:中间层按 *.shared.cs 规范保存的代码会 push 到表现层的 Generated_Code 文件夹内;文件链接:添加已存在文件时,选择“Add As Link”,此为 pull 模型</Run>
</TextBlock>
</StackPanel>
</Grid>
</navigation:Page>
2、演示 DomainDataSource 的应用
服务端:
MyDomainService.cs
代码
/*
* 一个 Domain Service 服务
*/
namespace Silverlight40.Web.Service
{
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Data;
using System.Linq;
using System.ServiceModel.DomainServices.EntityFramework;
using System.ServiceModel.DomainServices.Hosting;
using System.ServiceModel.DomainServices.Server;
using Silverlight40.Web.Model;
/*
* 用 LinqToEntities 实现 Domain Service 则继承 LinqToSqlDomainService<NorthwindEntities>;用 LinqToSql 实现 Domain Service 则继承 LinqToSqlDomainService<NorthwindEntities>
* Domain Service 内所有对客户端可见的方法都应该是 public 的,Domain Service 内的方法不支持重载
* 对客户端可见的方法要满足命名约定,或为其指定对应的 Attribute。当前支持 6 种数据操作:Query, Update, Insert, Delete, Invoke, Named Update, 详见文档
*
* [EnableClientAccess()] - 该类对客户端可见
* [EnableClientAccess(RequiresSecureEndpoint = true)] - 使用 HTTPS 协议
* [Ignore] - 指定的方法不作为服务而公开
* [Query(IsComposable=true)] - 支持客户端的 linq 查询,而且此查询会被在服务端执行
*
* 在多个 Domain Services 间共享实体:通过 [ExternalReference], [Association()], Context.AddReference() 实现,详见文档
*/
// 服务端的类名为:MyDomainService,则其生成的客户端上下文的类名为:MyDomainContext
[EnableClientAccess()]
public class MyDomainService : LinqToEntitiesDomainService<NorthwindEntities>
{
[Query(IsDefault = true)]
public IQueryable<Category> GetCategories()
{
return this.ObjectContext.Categories;
}
public void InsertCategory(Category category)
{
if ((category.EntityState != EntityState.Detached))
{
this.ObjectContext.ObjectStateManager.ChangeObjectState(category, EntityState.Added);
}
else
{
this.ObjectContext.Categories.AddObject(category);
}
}
public void UpdateCategory(Category currentCategory)
{
this.ObjectContext.Categories.AttachAsModified(currentCategory, this.ChangeSet.GetOriginal(currentCategory));
}
public void DeleteCategory(Category category)
{
if ((category.EntityState == EntityState.Detached))
{
this.ObjectContext.Categories.Attach(category);
}
this.ObjectContext.Categories.DeleteObject(category);
}
[Query(IsDefault = true)]
public IQueryable<Product> GetProducts()
{
return this.ObjectContext.Products;
}
public IQueryable<Product> GetProductsBySort(string sort)
{
return ObjectContext.Products.OrderBy(sort);
}
public void InsertProduct(Product product)
{
if ((product.EntityState != EntityState.Detached))
{
this.ObjectContext.ObjectStateManager.ChangeObjectState(product, EntityState.Added);
}
else
{
this.ObjectContext.Products.AddObject(product);
}
}
public void UpdateProduct(Product currentProduct)
{
this.ObjectContext.Products.AttachAsModified(currentProduct, this.ChangeSet.GetOriginal(currentProduct));
}
public void DeleteProduct(Product product)
{
if ((product.EntityState == EntityState.Detached))
{
this.ObjectContext.Products.Attach(product);
}
this.ObjectContext.Products.DeleteObject(product);
}
public IQueryable<Product> GetProductsByCategoryId(int categoryId)
{
return this.ObjectContext.Products.Where(p => p.CategoryID == categoryId);
}
}
}
* 一个 Domain Service 服务
*/
namespace Silverlight40.Web.Service
{
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Data;
using System.Linq;
using System.ServiceModel.DomainServices.EntityFramework;
using System.ServiceModel.DomainServices.Hosting;
using System.ServiceModel.DomainServices.Server;
using Silverlight40.Web.Model;
/*
* 用 LinqToEntities 实现 Domain Service 则继承 LinqToSqlDomainService<NorthwindEntities>;用 LinqToSql 实现 Domain Service 则继承 LinqToSqlDomainService<NorthwindEntities>
* Domain Service 内所有对客户端可见的方法都应该是 public 的,Domain Service 内的方法不支持重载
* 对客户端可见的方法要满足命名约定,或为其指定对应的 Attribute。当前支持 6 种数据操作:Query, Update, Insert, Delete, Invoke, Named Update, 详见文档
*
* [EnableClientAccess()] - 该类对客户端可见
* [EnableClientAccess(RequiresSecureEndpoint = true)] - 使用 HTTPS 协议
* [Ignore] - 指定的方法不作为服务而公开
* [Query(IsComposable=true)] - 支持客户端的 linq 查询,而且此查询会被在服务端执行
*
* 在多个 Domain Services 间共享实体:通过 [ExternalReference], [Association()], Context.AddReference() 实现,详见文档
*/
// 服务端的类名为:MyDomainService,则其生成的客户端上下文的类名为:MyDomainContext
[EnableClientAccess()]
public class MyDomainService : LinqToEntitiesDomainService<NorthwindEntities>
{
[Query(IsDefault = true)]
public IQueryable<Category> GetCategories()
{
return this.ObjectContext.Categories;
}
public void InsertCategory(Category category)
{
if ((category.EntityState != EntityState.Detached))
{
this.ObjectContext.ObjectStateManager.ChangeObjectState(category, EntityState.Added);
}
else
{
this.ObjectContext.Categories.AddObject(category);
}
}
public void UpdateCategory(Category currentCategory)
{
this.ObjectContext.Categories.AttachAsModified(currentCategory, this.ChangeSet.GetOriginal(currentCategory));
}
public void DeleteCategory(Category category)
{
if ((category.EntityState == EntityState.Detached))
{
this.ObjectContext.Categories.Attach(category);
}
this.ObjectContext.Categories.DeleteObject(category);
}
[Query(IsDefault = true)]
public IQueryable<Product> GetProducts()
{
return this.ObjectContext.Products;
}
public IQueryable<Product> GetProductsBySort(string sort)
{
return ObjectContext.Products.OrderBy(sort);
}
public void InsertProduct(Product product)
{
if ((product.EntityState != EntityState.Detached))
{
this.ObjectContext.ObjectStateManager.ChangeObjectState(product, EntityState.Added);
}
else
{
this.ObjectContext.Products.AddObject(product);
}
}
public void UpdateProduct(Product currentProduct)
{
this.ObjectContext.Products.AttachAsModified(currentProduct, this.ChangeSet.GetOriginal(currentProduct));
}
public void DeleteProduct(Product product)
{
if ((product.EntityState == EntityState.Detached))
{
this.ObjectContext.Products.Attach(product);
}
this.ObjectContext.Products.DeleteObject(product);
}
public IQueryable<Product> GetProductsByCategoryId(int categoryId)
{
return this.ObjectContext.Products.Where(p => p.CategoryID == categoryId);
}
}
}
MyDomainService.metadata.cs
代码
/*
* [MetadataTypeAttribute()] - 指定类的元数据对象
* [Include] - 生成的客户端上下文包含此字段
* [Exclude] - 生成的客户端上下文不包含此字段
* [Composition] - 指定字段为关联数据,即父实体增删改查时,此关联数据也会做相应的变化。指定此 Attribute 后,需显式指定其为 [Include]
* [Editable(true)], [Editable(false)] - 指定字段是否可编辑
*/
namespace Silverlight40.Web.Model
{
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Data.Objects.DataClasses;
using System.Linq;
using System.ServiceModel.DomainServices.Hosting;
using System.ServiceModel.DomainServices.Server;
[MetadataTypeAttribute(typeof(Category.CategoryMetadata))]
public partial class Category
{
internal sealed class CategoryMetadata
{
private CategoryMetadata()
{
}
[Key()]
public int CategoryID { get; set; }
[Display(Name = "类别名称")] // 显示用
public string CategoryName { get; set; }
public string Description { get; set; }
[Exclude]
public byte[] Picture { get; set; }
[Include]
// [Composition]
public EntityCollection<Product> Products { get; set; }
}
}
[MetadataTypeAttribute(typeof(Product.ProductMetadata))]
public partial class Product
{
internal sealed class ProductMetadata
{
private ProductMetadata()
{
}
public Category Category { get; set; }
public Nullable<int> CategoryID { get; set; }
public bool Discontinued { get; set; }
public EntityCollection<Order_Detail> Order_Details { get; set; }
[Display(Order = 0, Name = "产品ID")]
public int ProductID { get; set; }
[Display(Order = 1, Name = "产品名称")]
public string ProductName { get; set; }
public string QuantityPerUnit { get; set; }
public Nullable<short> ReorderLevel { get; set; }
public Supplier Supplier { get; set; }
public Nullable<int> SupplierID { get; set; }
public Nullable<decimal> UnitPrice { get; set; }
public Nullable<short> UnitsInStock { get; set; }
public Nullable<short> UnitsOnOrder { get; set; }
}
}
}
* [MetadataTypeAttribute()] - 指定类的元数据对象
* [Include] - 生成的客户端上下文包含此字段
* [Exclude] - 生成的客户端上下文不包含此字段
* [Composition] - 指定字段为关联数据,即父实体增删改查时,此关联数据也会做相应的变化。指定此 Attribute 后,需显式指定其为 [Include]
* [Editable(true)], [Editable(false)] - 指定字段是否可编辑
*/
namespace Silverlight40.Web.Model
{
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Data.Objects.DataClasses;
using System.Linq;
using System.ServiceModel.DomainServices.Hosting;
using System.ServiceModel.DomainServices.Server;
[MetadataTypeAttribute(typeof(Category.CategoryMetadata))]
public partial class Category
{
internal sealed class CategoryMetadata
{
private CategoryMetadata()
{
}
[Key()]
public int CategoryID { get; set; }
[Display(Name = "类别名称")] // 显示用
public string CategoryName { get; set; }
public string Description { get; set; }
[Exclude]
public byte[] Picture { get; set; }
[Include]
// [Composition]
public EntityCollection<Product> Products { get; set; }
}
}
[MetadataTypeAttribute(typeof(Product.ProductMetadata))]
public partial class Product
{
internal sealed class ProductMetadata
{
private ProductMetadata()
{
}
public Category Category { get; set; }
public Nullable<int> CategoryID { get; set; }
public bool Discontinued { get; set; }
public EntityCollection<Order_Detail> Order_Details { get; set; }
[Display(Order = 0, Name = "产品ID")]
public int ProductID { get; set; }
[Display(Order = 1, Name = "产品名称")]
public string ProductName { get; set; }
public string QuantityPerUnit { get; set; }
public Nullable<short> ReorderLevel { get; set; }
public Supplier Supplier { get; set; }
public Nullable<int> SupplierID { get; set; }
public Nullable<decimal> UnitPrice { get; set; }
public Nullable<short> UnitsInStock { get; set; }
public Nullable<short> UnitsOnOrder { get; set; }
}
}
}
客户端:
DomainDataSourceDemo.xaml
代码
<!--
System.Windows.Controls.DomainServices 程序集的默认位置:
C:\Program Files\Microsoft SDKs\RIA Services\v1.0\Libraries\Silverlight\System.Windows.Controls.DomainServices.dll
-->
<navigation:Page x:Class="Silverlight40.WCFRIAServices.DomainDataSourceDemo"
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"
xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
xmlns:riaControls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.DomainServices"
xmlns:my="clr-namespace:Silverlight40.Web.Service"
Title="DomainDataSourceDemo Page">
<Grid x:Name="LayoutRoot">
<StackPanel HorizontalAlignment="Left">
<!--
用于演示添加记录
-->
<StackPanel Orientation="Horizontal">
<sdk:Label Name="lblProductName4Add" Content="产品名称(添加用):" />
<TextBox Name="txtProductName4Add" Width="100" />
<Button Name="btnAdd" Content="新增" Click="btnAdd_Click" />
</StackPanel>
<!--
用于演示查询记录
-->
<StackPanel Orientation="Horizontal">
<sdk:Label Name="lblProductName" Content="产品名称(查询用):" />
<TextBox Name="txtProductName" Width="100" />
</StackPanel>
<!--
用于演示显示记录,更新记录,删除记录
将 DataGrid 的数据源绑定到 DomainDataSource 对象上,相关的查询排序等逻辑在 DomainDataSource 对象内设置
-->
<sdk:DataGrid Name="dataGrid" Width="600" Height="300" AutoGenerateColumns="False" ItemsSource="{Binding ElementName=productDomainDataSource, Path=Data}">
<sdk:DataGrid.Columns>
<sdk:DataGridTextColumn Header="供应商ID" Binding="{Binding SupplierID}" IsReadOnly="True" />
<sdk:DataGridTextColumn Header="产品类别ID" Binding="{Binding CategoryID}" IsReadOnly="True" />
<sdk:DataGridTextColumn Header="产品ID" Binding="{Binding ProductID}" IsReadOnly="True" />
<sdk:DataGridTextColumn Header="产品名称" Binding="{Binding ProductName}" />
<sdk:DataGridTemplateColumn Header="删除">
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid>
<Button Name="btnDelete" Content="删除" Click="btnDelete_Click" />
</Grid>
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
</sdk:DataGridTemplateColumn>
</sdk:DataGrid.Columns>
</sdk:DataGrid>
<!--
将 DataPager 的数据源绑定到 DomainDataSource 对象上,即可实现服务端分页
-->
<sdk:DataPager Name="dataPager" Width="600" Height="30" PageSize="5" Source="{Binding ElementName=productDomainDataSource, Path=Data}" />
<Button Name="btnSave" Content="保存" Click="btnSave_Click" />
</StackPanel>
<!--
DomainDataSource - 一种数据源控件,通过一个 Domain 上下文关联 UI 和 WCF RIA Services。其所有查询操作均在服务端完成
QueryName - 指定查询方法
AutoLoad - 是否自动加载数据
FilterOperator - 各个 FilterDescriptor 间的逻辑关系。“And”或“Or”
-->
<riaControls:DomainDataSource Name="productDomainDataSource" QueryName="GetProductsByCategoryIdQuery" AutoLoad="True" FilterOperator="Or">
<!--
指定数据上下文,来自 Silverlight40.Web.Service.MyDomainContext
-->
<riaControls:DomainDataSource.DomainContext>
<my:MyDomainContext />
</riaControls:DomainDataSource.DomainContext>
<!--
指定查询参数,为 GetProductsByCategoryId 方法传递参数,参数名:categoryId,参数值:1
-->
<riaControls:DomainDataSource.QueryParameters>
<riaControls:Parameter ParameterName="categoryId" Value="1" />
</riaControls:DomainDataSource.QueryParameters>
<!--
指定排序逻辑,按 SupplierID 字段正序排序
-->
<riaControls:DomainDataSource.SortDescriptors>
<riaControls:SortDescriptor Direction="Ascending" PropertyPath="SupplierID" />
</riaControls:DomainDataSource.SortDescriptors>
<!--
指定分组逻辑,按 SupplierID 字段分组显示
-->
<riaControls:DomainDataSource.GroupDescriptors>
<riaControls:GroupDescriptor PropertyPath="SupplierID" />
</riaControls:DomainDataSource.GroupDescriptors>
<!--
指定过滤逻辑,筛选逻辑为:ProductName 字段数据包含“a”或者 ProductName 字段数据包含 txtProductName.Text 中的内容
-->
<riaControls:DomainDataSource.FilterDescriptors>
<riaControls:FilterDescriptor Operator="Contains" PropertyPath="ProductName" Value="a" />
<riaControls:FilterDescriptor Operator="Contains" PropertyPath="ProductName" Value="{Binding ElementName=txtProductName, Path=Text}" />
</riaControls:DomainDataSource.FilterDescriptors>
</riaControls:DomainDataSource>
</Grid>
</navigation:Page>
System.Windows.Controls.DomainServices 程序集的默认位置:
C:\Program Files\Microsoft SDKs\RIA Services\v1.0\Libraries\Silverlight\System.Windows.Controls.DomainServices.dll
-->
<navigation:Page x:Class="Silverlight40.WCFRIAServices.DomainDataSourceDemo"
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"
xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
xmlns:riaControls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.DomainServices"
xmlns:my="clr-namespace:Silverlight40.Web.Service"
Title="DomainDataSourceDemo Page">
<Grid x:Name="LayoutRoot">
<StackPanel HorizontalAlignment="Left">
<!--
用于演示添加记录
-->
<StackPanel Orientation="Horizontal">
<sdk:Label Name="lblProductName4Add" Content="产品名称(添加用):" />
<TextBox Name="txtProductName4Add" Width="100" />
<Button Name="btnAdd" Content="新增" Click="btnAdd_Click" />
</StackPanel>
<!--
用于演示查询记录
-->
<StackPanel Orientation="Horizontal">
<sdk:Label Name="lblProductName" Content="产品名称(查询用):" />
<TextBox Name="txtProductName" Width="100" />
</StackPanel>
<!--
用于演示显示记录,更新记录,删除记录
将 DataGrid 的数据源绑定到 DomainDataSource 对象上,相关的查询排序等逻辑在 DomainDataSource 对象内设置
-->
<sdk:DataGrid Name="dataGrid" Width="600" Height="300" AutoGenerateColumns="False" ItemsSource="{Binding ElementName=productDomainDataSource, Path=Data}">
<sdk:DataGrid.Columns>
<sdk:DataGridTextColumn Header="供应商ID" Binding="{Binding SupplierID}" IsReadOnly="True" />
<sdk:DataGridTextColumn Header="产品类别ID" Binding="{Binding CategoryID}" IsReadOnly="True" />
<sdk:DataGridTextColumn Header="产品ID" Binding="{Binding ProductID}" IsReadOnly="True" />
<sdk:DataGridTextColumn Header="产品名称" Binding="{Binding ProductName}" />
<sdk:DataGridTemplateColumn Header="删除">
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid>
<Button Name="btnDelete" Content="删除" Click="btnDelete_Click" />
</Grid>
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
</sdk:DataGridTemplateColumn>
</sdk:DataGrid.Columns>
</sdk:DataGrid>
<!--
将 DataPager 的数据源绑定到 DomainDataSource 对象上,即可实现服务端分页
-->
<sdk:DataPager Name="dataPager" Width="600" Height="30" PageSize="5" Source="{Binding ElementName=productDomainDataSource, Path=Data}" />
<Button Name="btnSave" Content="保存" Click="btnSave_Click" />
</StackPanel>
<!--
DomainDataSource - 一种数据源控件,通过一个 Domain 上下文关联 UI 和 WCF RIA Services。其所有查询操作均在服务端完成
QueryName - 指定查询方法
AutoLoad - 是否自动加载数据
FilterOperator - 各个 FilterDescriptor 间的逻辑关系。“And”或“Or”
-->
<riaControls:DomainDataSource Name="productDomainDataSource" QueryName="GetProductsByCategoryIdQuery" AutoLoad="True" FilterOperator="Or">
<!--
指定数据上下文,来自 Silverlight40.Web.Service.MyDomainContext
-->
<riaControls:DomainDataSource.DomainContext>
<my:MyDomainContext />
</riaControls:DomainDataSource.DomainContext>
<!--
指定查询参数,为 GetProductsByCategoryId 方法传递参数,参数名:categoryId,参数值:1
-->
<riaControls:DomainDataSource.QueryParameters>
<riaControls:Parameter ParameterName="categoryId" Value="1" />
</riaControls:DomainDataSource.QueryParameters>
<!--
指定排序逻辑,按 SupplierID 字段正序排序
-->
<riaControls:DomainDataSource.SortDescriptors>
<riaControls:SortDescriptor Direction="Ascending" PropertyPath="SupplierID" />
</riaControls:DomainDataSource.SortDescriptors>
<!--
指定分组逻辑,按 SupplierID 字段分组显示
-->
<riaControls:DomainDataSource.GroupDescriptors>
<riaControls:GroupDescriptor PropertyPath="SupplierID" />
</riaControls:DomainDataSource.GroupDescriptors>
<!--
指定过滤逻辑,筛选逻辑为:ProductName 字段数据包含“a”或者 ProductName 字段数据包含 txtProductName.Text 中的内容
-->
<riaControls:DomainDataSource.FilterDescriptors>
<riaControls:FilterDescriptor Operator="Contains" PropertyPath="ProductName" Value="a" />
<riaControls:FilterDescriptor Operator="Contains" PropertyPath="ProductName" Value="{Binding ElementName=txtProductName, Path=Text}" />
</riaControls:DomainDataSource.FilterDescriptors>
</riaControls:DomainDataSource>
</Grid>
</navigation:Page>
DomainDataSourceDemo.xaml.cs
代码
/*
* 演示通过 DomainDataSource 实现数据的添加、查询、更新和删除操作,以及服务端的查询、排序和分页等逻辑
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Navigation;
using Silverlight40.Web.Model;
using System.ServiceModel.DomainServices.Client;
namespace Silverlight40.WCFRIAServices
{
public partial class DomainDataSourceDemo : Page
{
public DomainDataSourceDemo()
{
InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
// DomainDataSource.SubmitChanges() - 提交数据的变化
// DomainDataSource.SubmittingChanges - SubmitChanges() 执行前所触发的事件
// DomainDataSource.SubmittedChanges - SubmitChanges() 执行后所触发的事件
// DomainDataSource.Load() - 加载查询结果
productDomainDataSource.SubmittingChanges += new EventHandler<SubmittingChangesEventArgs>(productDomainDataSource_SubmittingChanges);
productDomainDataSource.SubmittedChanges += new EventHandler<SubmittedChangesEventArgs>(productDomainDataSource_SubmittedChanges);
}
private void productDomainDataSource_LoadedData(object sender, LoadedDataEventArgs e)
{
if (e.HasError)
{
System.Windows.MessageBox.Show(e.Error.ToString(), "Load Error", System.Windows.MessageBoxButton.OK);
e.MarkErrorAsHandled();
}
}
private void btnSave_Click(object sender, RoutedEventArgs e)
{
productDomainDataSource.SubmitChanges();
}
void productDomainDataSource_SubmittingChanges(object sender, SubmittingChangesEventArgs e)
{
MessageBox.Show("Submitting");
}
void productDomainDataSource_SubmittedChanges(object sender, SubmittedChangesEventArgs e)
{
if (e.HasError)
{
MessageBox.Show(e.Error.ToString());
}
else
{
MessageBox.Show("Submitted");
productDomainDataSource.Load();
}
}
private void btnAdd_Click(object sender, RoutedEventArgs e)
{
// DomainDataSource.DomainContext - 数据上下文对象 [System.ServiceModel.DomainServices.Client.DomainContext 类型]
// DomainContext.EntityContainer - 数据上下文对象中的全部实体 [System.ServiceModel.DomainServices.Client.EntityContainer 类型]
// EntityContainer.GetEntitySet<T>() - 获取指定类型的实体数据
EntitySet<Product> products = productDomainDataSource.DomainContext.EntityContainer.GetEntitySet<Product>();
Product product = new Product();
product.ProductName = txtProductName4Add.Text;
product.CategoryID = 1;
product.SupplierID = 1;
products.Add(product);
productDomainDataSource.SubmitChanges();
}
private void btnDelete_Click(object sender, RoutedEventArgs e)
{
EntitySet<Product> products = productDomainDataSource.DomainContext.EntityContainer.GetEntitySet<Product>();
Product product = dataGrid.SelectedItem as Product;
products.Remove(product);
productDomainDataSource.SubmitChanges();
}
}
}
* 演示通过 DomainDataSource 实现数据的添加、查询、更新和删除操作,以及服务端的查询、排序和分页等逻辑
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Navigation;
using Silverlight40.Web.Model;
using System.ServiceModel.DomainServices.Client;
namespace Silverlight40.WCFRIAServices
{
public partial class DomainDataSourceDemo : Page
{
public DomainDataSourceDemo()
{
InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
// DomainDataSource.SubmitChanges() - 提交数据的变化
// DomainDataSource.SubmittingChanges - SubmitChanges() 执行前所触发的事件
// DomainDataSource.SubmittedChanges - SubmitChanges() 执行后所触发的事件
// DomainDataSource.Load() - 加载查询结果
productDomainDataSource.SubmittingChanges += new EventHandler<SubmittingChangesEventArgs>(productDomainDataSource_SubmittingChanges);
productDomainDataSource.SubmittedChanges += new EventHandler<SubmittedChangesEventArgs>(productDomainDataSource_SubmittedChanges);
}
private void productDomainDataSource_LoadedData(object sender, LoadedDataEventArgs e)
{
if (e.HasError)
{
System.Windows.MessageBox.Show(e.Error.ToString(), "Load Error", System.Windows.MessageBoxButton.OK);
e.MarkErrorAsHandled();
}
}
private void btnSave_Click(object sender, RoutedEventArgs e)
{
productDomainDataSource.SubmitChanges();
}
void productDomainDataSource_SubmittingChanges(object sender, SubmittingChangesEventArgs e)
{
MessageBox.Show("Submitting");
}
void productDomainDataSource_SubmittedChanges(object sender, SubmittedChangesEventArgs e)
{
if (e.HasError)
{
MessageBox.Show(e.Error.ToString());
}
else
{
MessageBox.Show("Submitted");
productDomainDataSource.Load();
}
}
private void btnAdd_Click(object sender, RoutedEventArgs e)
{
// DomainDataSource.DomainContext - 数据上下文对象 [System.ServiceModel.DomainServices.Client.DomainContext 类型]
// DomainContext.EntityContainer - 数据上下文对象中的全部实体 [System.ServiceModel.DomainServices.Client.EntityContainer 类型]
// EntityContainer.GetEntitySet<T>() - 获取指定类型的实体数据
EntitySet<Product> products = productDomainDataSource.DomainContext.EntityContainer.GetEntitySet<Product>();
Product product = new Product();
product.ProductName = txtProductName4Add.Text;
product.CategoryID = 1;
product.SupplierID = 1;
products.Add(product);
productDomainDataSource.SubmitChanges();
}
private void btnDelete_Click(object sender, RoutedEventArgs e)
{
EntitySet<Product> products = productDomainDataSource.DomainContext.EntityContainer.GetEntitySet<Product>();
Product product = dataGrid.SelectedItem as Product;
products.Remove(product);
productDomainDataSource.SubmitChanges();
}
}
}
OK
[源码下载]