通过 ViewState 保存 Self-Tracking Entities
如果你希望能够在 ViewState 中保存 Self-Tracking Entities 对象,那么,将会遇到不能序列化的问题。
问题的原因在于 ViewState 通过将对象序列化之后通过隐藏域保存在网页中,所以,希望通过 ViewState 进行状态管理的对象必须支持序列化。
但是 Self-Tracking Entities 中生成的类没有序列化的标签,所以,导致使用失败。
幸运的是,Self-Tracking Entities 是通过 T4 - Text Template Transformation Toolkit 来生成代码的。
关于 T4 - Text Template Transformation Toolkit 可以参考我的另外一篇文章。VS2010 中的代码生成器 T4 - Text Template Transformation Toolkit
默认的 Self-Tracking Entities 模板中没有包含我们需要的标记说明来支持序列化,好消息就是我们可以简单的编辑一下 Self-Tracking Entities 的 T4 模板就可以了。
我们需要这几步就可以:
1. 增加 [Serializable] 标签到实体,复杂类型和集合类
2. 为字典集合类增加必须的序列化构造器
3. 为实体和复杂类型的 OnDerserializedMethod 方法增加一些代码,当一个实体被反序列化的时候来注册变化的跟踪事件
但是在 Silverlight 中还没有二进制的序列化。所以,如果你做了上面第1 和第 2 步的修改,那么,在 Silverlight 中将不能通过编译。
Self-Tracking Entities 在你的项目中加入了两个模板,其中一个用来生成 ObjectContext ,另外一个用来生成实体,我们需要修改的内容就在第二个用来生成实体的模板中。
第一件事就是给所有的类增加 [Serializable] 标签 以支持序列化。
先找到 37 行,增加 [Serializable] 后,应该如下所示:
38 <#=Accessibility.ForType(entity)#> <#=code.SpaceAfter(code.AbstractOption(entity))#>partial class <#=code.Escape(entity)#><#=code.StringBefore(" : ", code.Escape(entity.BaseType))#><#=entity.BaseType == null ? ": " : ", "#>IObjectWithChangeTracker, INotifyPropertyChanged
后面的修改依次如下。
1404: public class TrackableCollection<T> : ObservableCollection<T>
1405: {
1429: public class ObjectChangeTracker
1430: {
1651: public class ObjectsAddedToCollectionProperties : Dictionary<string, ObjectList>
1652 { }
1656: public class ObjectsRemovedFromCollectionProperties : Dictionary<string,
ObjectList> { }
1661: public class OriginalValuesDictionary : Dictionary<string, Object> { }
1666: public class ExtendedPropertiesDictionary : Dictionary<string, Object> { }
1670: public class ObjectList : List<object> { }
序列化构造器
下一步,我们要确认所有从 Dictionary<> 派生的类都完全支持序列化。
由于 Dictionary<> 类通过实现接口 ISerializable 来实现了自定义的序列化,所以,所有派生自 Dictionary<> 的类必须有一个特制的用于反序列化的构造函数。
并不需要我们为构造函数增加什么代码,仅仅需要有构造函数来支持 Dictionary<> 的反序列化。这里有四个类需要做修改。
ObjectsAddedToCollectionProperties 类
1652: {
1653: public ObjectsAddedToCollectionProperties() { }
1654:
1655: protected ObjectsAddedToCollectionProperties(SerializationInfo info,
1656: StreamingContext ctx)
1657: : base(info, ctx)
1658: { }
1659: }
ObjectsRemovedFromCollectionProperties 类
1665: {
1666: public ObjectsRemovedFromCollectionProperties() { }
1667:
1668: protected ObjectsRemovedFromCollectionProperties(SerializationInfo info,
1669: StreamingContext ctx)
1670: : base(info, ctx)
1671: { }
1672: }
OriginalValuesDictionary 类
1678: {
1679: public OriginalValuesDictionary() { }
1680:
1681: protected OriginalValuesDictionary(SerializationInfo info,
1682: StreamingContext ctx)
1683: : base(info, ctx)
1684: { }
1685: }
最后,ExtendedPropertiesDictionary 类
1691: {
1692: public ExtendedPropertiesDictionary() { }
1693:
1694: protected ExtendedPropertiesDictionary(SerializationInfo info,
1695: StreamingContext ctx)
1696: : base(info, ctx)
1697: { }
1698: }
事件的处理
由于在进行二进制序列化的时候不会序列化事件的处理,所以,在反序列化之后,我们可以通过 OnDeserialized 方法来执行一些我们自己的代码完成这个工作。
为了给实体增加这些工作,我们可以在模板中找到 OnDeserializedMethod 方法,然后增加三种重要的事件处理:
复杂类型事件处理
双向连接的集合属性的事件处理
级联删除的事件处理
将原来的 OnDeserializedMethod 方法直接用下面的替换掉
public void OnDeserializedMethod(StreamingContext context)
{
IsDeserializing = false;
ChangeTracker.ChangeTrackingEnabled = true;
<#
// Hook up ComplexType property event handlers
foreach(EdmProperty edmProperty in entity.Properties
.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == entity))
{
#>
if (<#=code.FieldName(edmProperty)#> != null)
{
((INotifyComplexPropertyChanging)<#=code.FieldName(edmProperty)#>)
.ComplexPropertyChanging -= Handle<#=edmProperty.Name#>Changing;
((INotifyComplexPropertyChanging)<#=code.FieldName(edmProperty)#>)
.ComplexPropertyChanging += Handle<#=edmProperty.Name#>Changing;
}
<#
}
// Hook up Collection property event handlers
foreach (NavigationProperty navProperty in entity.NavigationProperties
.Where(np => np.DeclaringType == entity))
{
if (navProperty.ToEndMember.RelationshipMultiplicity ==
RelationshipMultiplicity.Many)
{
#>
if (<#=code.FieldName(navProperty)#> != null)
{
<#=code.FieldName(navProperty)#>.CollectionChanged -= Fixup<#=navProperty.Name#>;
<#=code.FieldName(navProperty)#>.CollectionChanged += Fixup<#=navProperty.Name#>;
<#
if (ef.IsCascadeDeletePrincipal(navProperty))
{
#>
// This is the principal end in an association that performs cascade deletes.
// Add the cascade delete event handler for any entities that are
// already in the collection.
foreach (var item in <#=code.FieldName(navProperty)#>)
{
ChangeTracker.ObjectStateChanging -= item.HandleCascadeDelete;
ChangeTracker.ObjectStateChanging += item.HandleCascadeDelete;
}
<#
}
#>
}
<#
}
}
#>
}
完成上面的这些修改之后,你的 self-tracking entities 应该可以进行二进制序列化了,也就可以通过 ViewState 进行状态管理。
在 Jeff Derstadt 的文章 Using Binary Serialization and ViewState with Self-Tracking Entities 中,还给出了一个已经修改好的模版文件,这是链接地址:完成的模版
这篇文章来自:Jeff Derstadt 的文章,这是原文的链接:http://blogs.msdn.com/b/adonet/archive/2010/05/26/using-binary-serialization-and-viewstate-with-self-tracking-entities.aspx
转载于:https://www.cnblogs.com/haogj/archive/2010/06/12/1757449.html
通过 ViewState 保存 Self-Tracking Entities相关推荐
- ASP.Net ViewState的实现
选择自 timmy3310 的 Blog ViewState是.Net中提出的状态保存的一种新途径(实际上也是老瓶装新酒):我们知道,传统的Web程序保存状态的方式有这样几种: 1.Applica ...
- 艾伟:控件之ViewState
主题,控件的viewstate状态 一"七七八八" 有次,朋友开玩笑说,不知道什么时候,微软会取消viewstate,不再使用隐藏字段在服务器与客户端保存状态!虽然,可以使用客户端 ...
- ViewState与Session 的重要区别
ViewState 指的是当前页面的视图状态(不同于控件的视图状态), ViewState 可以将任意支持序列化的对象保存到页面中, 它与 Session 的重要区别有两个: 第一.ViewState ...
- [转]用 ASP.NET 2.0 改进的 ViewState 加快网站速度
本文讨论: • ViewState 如何工作 • ASP.NET 2.0 ViewState 的改进 • 使用控件状态维护功能 • 性能考虑 本文使用以下技术: ASP.NET.C# 代码下载: Vi ...
- .Net ViewState的实现(转载)
ViewState是.Net中提出的状态保存的一种新途径(实际上也是老瓶装新酒):我们知道,传统的Web程序保存状态的方式有这样几种: 1.Application 这是Web应用程序生命期中的全局 ...
- [木野狐]ViewState 剖析(翻译兼笔记)
[木野狐]ViewState 剖析(翻译兼笔记) 原文链接:ViewState: All You Wanted to Know 作者:Paul Wilson翻译:木野狐 ViewState 不是什么? ...
- viewstate java_ASP.NET之ViewState
什么是ViewState? 在asp时代, 大家都知道一个html控件的值,比如input 控件值,当我们把表单提交到服务器后, 页面再刷新回来的时候, input里面的数据已经被清空. 这是因为we ...
- HttpApplication事件ASP.NET页面周期
学习吧少年........................... 修改中........... 当一次请求到达IIS 1.http.sys将请求发送到指定的应用程序池. 2.应用程序池再将请求交给池中 ...
- .net面试问题汇总(转)
用.net做B/S结构的系统,您是用几层结构来开发,每一层之间的关系以及为什么要这样分层? 答: 从下至上分别为:数据访问层.业务逻辑层(又或成为领域层).表示层 数据访问层:有时候也称为是持久层,其 ...
最新文章
- 计算机图学测试题及答案,《计算机图形学》练习测试题及参考答案
- 互联网晚报 | 3月15日 星期二 |​ 特斯拉Model 3高性能版和Model Y长续版再涨价;字节成都成立光合科技公司...
- Github 1300+ 星!旷视开源的深度强化学习绘画智能体论文解读
- 使用正则表达式把关键字替换加粗
- JavaWeb开发Servlet学习
- Matlab求矩阵均值
- 【U盘量产】你的U盘坏了吗
- 判断经纬度是否落在中国地图上
- 利用Anaconda Prompt在Jupter notebook中安装包
- Python-qqbot实现QQ群翻译机器人
- 关闭打印机和无线服务器,打印机无线连接断开了怎么办?
- Bash cp 命令详解
- 基金直销账户体系介绍
- 成功解决Unexpected end of JSON input while parsing near的问题
- SOA为什么不“香”了?| 建设数据中台系列(三)
- 2022AP微积分AB北美卷FRQ已放出,附考情分析
- Kubernetes学习笔记(二)------什么是Kubernetes
- windows 删除文件夹 拒绝访问
- 转专业选择计算机的理由,转专业的理由如何描写?
- virtualbox 创建桥接网络_virtualbox下linux虚拟机的网络配置——桥接网络