WCF RIA Services 允许您创建从数据访问层的多个实体聚合数据的数据模型,即表示模型。当您不想直接将数据访问层中的实体公开给客户端时,可以使用此功能。使用表示模型时,可以通过只更改表示模型而不更改客户端来响应数据访问层中的更改。此外,通过设计只聚合与客户端的用户有关的那些字段的模型,可以简化客户端代码。本主题说明如何创建、查询和更新一个表示模型以及在中间层或数据源中设置更改时如何将值传回客户端。
本Demo演示的是,要取表一中的部分字段,表二中的部分字段,表三中的部分字段,把三个表整合到一个表示模型中,显示在客户端,
表一是模块表Widget,表二是角色表,aspnet_role,表三是模块角色关系表WidgeIntRole,
要取出Widget表中的ID列和Name列,取出角色表中的aspnet_role中的角色名,和WidgeIntRole表中的ID列,组合成一个新集合绑定DataGrid集合上,
做法:创建表示模型,新建一个类包含所需的字段:
表示模型类
1 public class ModuteRole
2 {
3 [Key]
4 public int ID { get; set; }
5 public int ModuteID { get; set; }
6 public string ModuteName { get; set; }
7 public Guid RoleID { get; set; }
8 public string RoleName { get; set; }
9 }
2 {
3 [Key]
4 public int ID { get; set; }
5 public int ModuteID { get; set; }
6 public string ModuteName { get; set; }
7 public Guid RoleID { get; set; }
8 public string RoleName { get; set; }
9 }
下一步:
客户端调用如下:
创建表示模型后,通过添加与表示类型交互的域服务,将该模型公开给客户端项目。只通过此域服务公开实体值
,而不通过公开整个实体的域服务来公开。下面的示例显示从 DomainService 类派生的域服务。
域服务
1 [EnableClientAccess()]
2 public class CustomsTypeDomainService : DomainService
3 {
4 RAPEntities rapEntities = new RAPEntities();
5 ///
6 ///
7 }
2 public class CustomsTypeDomainService : DomainService
3 {
4 RAPEntities rapEntities = new RAPEntities();
5 ///
6 ///
7 }
为了查询所需要的角色模块数据,需要添加一个查询方法到域服务中。在该查询方法中,把查询出来的RoleID,RolName,WidgetID,WidgetName,widgetRoleID字段属性赋给表示模型类中的对应属性,最后返回表示模型类集合。示例如下:
查询方法
1 /// <summary>
2 /// 返回模块与角色关系
3 /// </summary>
4 /// <param name="id">模块ID</param>
5 /// <returns></returns>
6 public IQueryable<ModuteRole> GetModuteRole(int id)
7 {
8 return from w in rapEntities.Widget
9 join wr in rapEntities.WidgetsInRoles on w.ID equals wr.WidgetId
10 join r in rapEntities.aspnet_Roles on wr.RoleId equals r.RoleId
11 where w.ID==id
12 select new ModuteRole()
13 {
14 ID=wr.Id,
15 ModuteID=w.ID,
16 ModuteName=w.Name,
17 RoleID=r.RoleId,
18 RoleName=r.RoleName
19 };
20
21 }
2 /// 返回模块与角色关系
3 /// </summary>
4 /// <param name="id">模块ID</param>
5 /// <returns></returns>
6 public IQueryable<ModuteRole> GetModuteRole(int id)
7 {
8 return from w in rapEntities.Widget
9 join wr in rapEntities.WidgetsInRoles on w.ID equals wr.WidgetId
10 join r in rapEntities.aspnet_Roles on wr.RoleId equals r.RoleId
11 where w.ID==id
12 select new ModuteRole()
13 {
14 ID=wr.Id,
15 ModuteID=w.ID,
16 ModuteName=w.Name,
17 RoleID=r.RoleId,
18 RoleName=r.RoleName
19 };
20
21 }
客户端调用代码
删除演示如下:
1 private CustomsTypeDomainContext customsTypeDomainContext = new CustomsTypeDomainContext();
2 public Widget widget { get; set; }
3 public Page1()
4 {
5 InitializeComponent();
6 widget = new Widget();
7 }
8
9 /// <summary>
10 /// 绑定模块与角色关系表
11 /// </summary>
12 public void BindWidgetRole()
13 {
14 Action<LoadOperation<ModuteRole>> moduteCallBack = new Action<LoadOperation<ModuteRole>>(ModuteRoleLoaded);
15 LoadOperation<ModuteRole> tempOp = customsTypeDomainContext.Load(customsTypeDomainContext.GetModuteRoleQuery(widget.ID), moduteCallBack, null);
16 moduteRoleDataGrid.ItemsSource = tempOp.Entities;
17 }
18
19 void ModuteRoleLoaded(LoadOperation<ModuteRole> e)
20 {
21 if (e.HasError)
22 {
23 MessageBox.Show("数据库加载错误:" + e.Error.ToString(), "提示", MessageBoxButton.OK);
24 e.MarkErrorAsHandled();
25 }
26 if (e.IsComplete)
27 {
28
29 }
30 }
2 public Widget widget { get; set; }
3 public Page1()
4 {
5 InitializeComponent();
6 widget = new Widget();
7 }
8
9 /// <summary>
10 /// 绑定模块与角色关系表
11 /// </summary>
12 public void BindWidgetRole()
13 {
14 Action<LoadOperation<ModuteRole>> moduteCallBack = new Action<LoadOperation<ModuteRole>>(ModuteRoleLoaded);
15 LoadOperation<ModuteRole> tempOp = customsTypeDomainContext.Load(customsTypeDomainContext.GetModuteRoleQuery(widget.ID), moduteCallBack, null);
16 moduteRoleDataGrid.ItemsSource = tempOp.Entities;
17 }
18
19 void ModuteRoleLoaded(LoadOperation<ModuteRole> e)
20 {
21 if (e.HasError)
22 {
23 MessageBox.Show("数据库加载错误:" + e.Error.ToString(), "提示", MessageBoxButton.OK);
24 e.MarkErrorAsHandled();
25 }
26 if (e.IsComplete)
27 {
28
29 }
30 }
下面将演示:更新删除表示模型
更新:
更新
1 [Update]
2 public void UpdateModuteRole(ModuteRole moduteRole)
3 {
4 aspnet_Roles roleEntity = rapEntities.aspnet_Roles.Where(r=>r.RoleId==moduteRole.RoleID).FirstOrDefault();
5 Widget WidgetEntity = rapEntities.Widget.Where(w => w.ID == moduteRole.ModuteID).FirstOrDefault();
6 WidgetsInRoles widgetsInRolesEntity = rapEntities.WidgetsInRoles.Where(wr=>wr.RoleId==moduteRole.RoleID&&wr.WidgetId==moduteRole.ModuteID).FirstOrDefault();
7
8 ModuteRole originalValues = this.ChangeSet.GetOriginal(moduteRole);
9
10 //字段更改业务逻辑
11
12 rapEntities.SaveChanges();
13
14 this.ChangeSet.Associate(moduteRole, roleEntity, MapCustomerToCustomerPM);
15 this.ChangeSet.Associate(moduteRole, WidgetEntity, MapAddressToCustomerPM);
16 }
17
18 [Ignore]
19 private void MapCustomerToCustomerPM(ModuteRole moduteRole, aspnet_Roles role)
20 {
21 moduteRole.RoleName = role.RoleName;
22 moduteRole.RoleID = role.RoleId;
23 }
24
25 [Ignore]
26 private void MapAddressToCustomerPM(ModuteRole moduteRole, Widget currentWidget)
27 {
28 moduteRole.ModuteName = currentWidget.Name;
29 moduteRole.ModuteID = currentWidget.ID;
30 }
2 public void UpdateModuteRole(ModuteRole moduteRole)
3 {
4 aspnet_Roles roleEntity = rapEntities.aspnet_Roles.Where(r=>r.RoleId==moduteRole.RoleID).FirstOrDefault();
5 Widget WidgetEntity = rapEntities.Widget.Where(w => w.ID == moduteRole.ModuteID).FirstOrDefault();
6 WidgetsInRoles widgetsInRolesEntity = rapEntities.WidgetsInRoles.Where(wr=>wr.RoleId==moduteRole.RoleID&&wr.WidgetId==moduteRole.ModuteID).FirstOrDefault();
7
8 ModuteRole originalValues = this.ChangeSet.GetOriginal(moduteRole);
9
10 //字段更改业务逻辑
11
12 rapEntities.SaveChanges();
13
14 this.ChangeSet.Associate(moduteRole, roleEntity, MapCustomerToCustomerPM);
15 this.ChangeSet.Associate(moduteRole, WidgetEntity, MapAddressToCustomerPM);
16 }
17
18 [Ignore]
19 private void MapCustomerToCustomerPM(ModuteRole moduteRole, aspnet_Roles role)
20 {
21 moduteRole.RoleName = role.RoleName;
22 moduteRole.RoleID = role.RoleId;
23 }
24
25 [Ignore]
26 private void MapAddressToCustomerPM(ModuteRole moduteRole, Widget currentWidget)
27 {
28 moduteRole.ModuteName = currentWidget.Name;
29 moduteRole.ModuteID = currentWidget.ID;
30 }
删除模块角色关系
1 /// <summary>
2 /// 删除角色模块关系
3 /// </summary>
4 /// <param name="currentModuteRole"></param>
5 public void DeleteModuteRole(ModuteRole currentModuteRole)
6 {
7 WidgetsInRoles widgetsInRolesEntity = rapEntities.WidgetsInRoles.Where(wr => wr.RoleId == currentModuteRole.RoleID && wr.WidgetId == currentModuteRole.ModuteID).FirstOrDefault();
8 this.rapEntities.WidgetsInRoles.DeleteObject(widgetsInRolesEntity);
9 }
2 /// 删除角色模块关系
3 /// </summary>
4 /// <param name="currentModuteRole"></param>
5 public void DeleteModuteRole(ModuteRole currentModuteRole)
6 {
7 WidgetsInRoles widgetsInRolesEntity = rapEntities.WidgetsInRoles.Where(wr => wr.RoleId == currentModuteRole.RoleID && wr.WidgetId == currentModuteRole.ModuteID).FirstOrDefault();
8 this.rapEntities.WidgetsInRoles.DeleteObject(widgetsInRolesEntity);
9 }
先前的做法是:先查出三个表中的所有集合到客户端,
然后在三个集合中连接查询,再绑定到DataGrid,这样要做三次异步操作,性能差是不言而喻的,而且也查询出了很多不相关的信息,在本Demo只作了一次查询,过滤掉了无关的信息,不知道还没有更好的做法,抛砖引玉吧.