框架有更新,主要对复合实体 结合了导航属性的应用,RIA-Silverlight 3程序开发框架-2 RIA-Silverlight 3程序开发框架-3
Silverlight程序开发的一些心得,
开始本希望把 Entity 和 DomainContext 尽可能分离,UI 操作 Entity,而不关心DomainContext,最后的架构其实又回到了The Entity Framework 原本的架构,因为数据库设计和导航属性的一些不便,对于复杂的实体,在原本的架构加入了一层BusinessContext(BusinessObject)
RIA-Silverlight程序架构
1. 背景知识:
a) 数据驱动:UI(DataContext BindingSource)→DomainContext (Entity) →DomainService→ObjectContext(EntityObject) → DataBase
DomainService前为Client端,后为Server端
RIAService:RIA架构中Client端与Server端通过RIAService沟通。 The Entity Framework 中这个 RIAService 就是LinqToEntitiesDomainService:DomainService
b) EntityChangeSet→ChangeSet:RIA减少了Server端的访问,多以批量的方式操作, 需要知道此次操作的内容。The Entity Framework 中 对应的就是实体变化集DomainContext. EntityContainer. EntityChangeSet→ DomainService. ChangeSet 。通过DomainContext.SubmitChanges() →DomainService .Submit(ChangeSet changeSet){备注1} → ObjectContext .SaveChanges() 数据流向DataBase
2. 程序架构:
由于
a) DomainContext (Entity) → DomainService,
Client端与Server端能够正常通讯的数据模型只能是 Entity,与DomainService沟通的只能是DomainContext
b) EntityChangeSet→ChangeSet,
如何获得EntityChangeSet?通过DomainContext(上下文)。DomainContext会记录
1. 该上下文中所有Entity的改变
2. Entity在该上下文中的所有改变,即 从Entity添加到该上下文以后 到 Entity脱离该上下文(备注2),
UI的操作必须影响到 位于DomainContext中的Entity,才可使架构运转。
初定RIA-Silverlight程序开发架构如下:
a) 架构1: 用于 简单实体-Entity
UI→DomainContext (Entity) →DomainService→ObjectContext(EntityObject) → DataBase
1. UI (Binding) DomainContext (Entity)
2. UI不能出现Load(EntityQurey), 以扩展方法 的方式,将其封装在DomainContext中,还应扩展 DomainContext 中其他常用方法 以及 其中Entity的常用方法
a) 架构2: 用于 复杂实体-BusinessObject (BusinessObject结构见 备注3)
UI→BusinessContext(BusinessObject)→DomainContext (Entity) →DomainService→ObjectContext(EntityObject) → DataBase
1. UI (Binding) BusinessContext(BusinessObject),在UI和DomainContext间加一层BusinessContext
2. BusinessContext 封装若干 DomainContext,以事件方式保证两者数据同步
3. BusinessObject 封装若干Entity或Entities,
4. BusinessContext 维护的是BusinessObject,应尽可能避免让BusinessContext对扩展属性进行操作(原因见 备注4)
备注1:关于DomainService .Submit(ChangeSet changeSet)
DomainService .Submit(ChangeSet changeSet)
{
AuthorizeChangeSet(ChangeSet changeSet);
ValidateChangeSet(ChangeSet changeSet) ;
ExecuteChangeSet(ChangeSet changeSet);(分析实体变化集(包含自定义的业务方法),按照约定规则调用服务中的相关方法)
PersistChangeSet(ChangeSet changeSet) ;
ResolveChangeSet(ChangeSet changeSet)
}
备注2:DomainContext与EntityChangeSet
DomainContext初始化时会创建EntityContainer,
1. EntityContainer会跟踪该容器中实体集的改变
2. EntityContainer只能跟踪Entity加入到该容器以后到脱离该容器之前的改变
public EntityContainer EntityContainer { get; } DomainContext中EntityContainer是只读的
protected override EntityContainer CreateEntityContainer()
{
return new DomainContextEntityContainer()
{
//这里会创建该DomainContext对应的DomainService可操作的Entity的EntitySet
this.CreateEntitySet<TEntity1>(EntitySetOperations.All);
this.CreateEntitySet< TEntity2>(EntitySetOperations.All);
};
}
备注3:BusinessObject结构:
Master(Entity)(主档信息)、Details(Entities)(从档信息)、PropertyExtend(Entity | Entities)(扩展属性)
以订单为例:
1. 主档信息:订单信息的Entity
2. 从档信息:订单明细 Entities
3. 扩展属性:订单主档中会有下单人信息,从档中会有商品信息,这些信息我们只在订单档种存放ID,更详细的信息在其他表中,我们命名为扩展属性。
备注4:尽量避免BusinessContext对扩展属性进行操作原因:
1. 上下文的功能应尽量明确
2. 若该页面若还存在 其他 对 该扩展属性 的维护,如果两者维护的不是同一数据,需要考虑数据的一致
闲扯一句,个人认为,Silverlight中UI用Binding的方式绑定数据,并提供不同的Mode,是一个很棒的设计思想。应用程序本就是对数据的处理,主线应该是数据,UI也是为数据服务的,asp.net的设计中,UI和数据有些分离,而且UI的分量有些重,主线不清楚,Bindging的方式,使我们可以专心于数据。