通过 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] 后,應該如下所示:
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
?
?
?后面的修改依次如下。
1403:?[Serializable]1404:?public?class?TrackableCollection<T>?:?ObservableCollection<T>
1405:?{
?
1428:?[Serializable]1429:?public?class?ObjectChangeTracker
1430:?{
?
1650:?[Serializable]1651:?public?class?ObjectsAddedToCollectionProperties?:?Dictionary<string,?ObjectList>
1652??{?}
?
1655:?[Serializable]1656:?public?class?ObjectsRemovedFromCollectionProperties?:?Dictionary<string,
???????ObjectList>?{?}
?
1660:?[Serializable]1661:?public?class?OriginalValuesDictionary?:?Dictionary<string,?Object>?{?}
?
1665:?[Serializable]1666:?public?class?ExtendedPropertiesDictionary?:?Dictionary<string,?Object>?{?}
?
1669:?[Serializable]1670:?public?class?ObjectList?:?List<object>?{?}
?
序列化構造器
?
下一步,我們要確認所有從?Dictionary<> 派生的類都完全支持序列化。
由于 Dictionary<> 類通過實現接口 ?ISerializable 來實現了自定義的序列化,所以,所有派生自 Dictionary<> 的類必須有一個特制的用于反序列化的構造函數。
并不需要我們為構造函數增加什么代碼,僅僅需要有構造函數來支持 ?Dictionary<>? 的反序列化。這里有四個類需要做修改。
ObjectsAddedToCollectionProperties 類
?1651:?public?class?ObjectsAddedToCollectionProperties?:?Dictionary<string,?ObjectList>?1652:?{
?1653:?????public?ObjectsAddedToCollectionProperties()?{?}
?1654:
?1655:?????protected?ObjectsAddedToCollectionProperties(SerializationInfo?info,
?1656:??????????????????????????????????????????????????StreamingContext?ctx)?
?1657:?????????:?base(info,?ctx)
?1658:?????{?}
?1659:?}
?
ObjectsRemovedFromCollectionProperties 類
?
?1664:?public?class?ObjectsRemovedFromCollectionProperties?:?Dictionary<string,?ObjectList>?1665:?{
?1666:?????public?ObjectsRemovedFromCollectionProperties()?{?}
?1667:
?1668:?????protected?ObjectsRemovedFromCollectionProperties(SerializationInfo?info,?
?1669:??????????????????????????????????????????????????????StreamingContext?ctx)?
?1670:????????:?base(info,?ctx)
?1671:????{?}
?1672:?}
OriginalValuesDictionary 類
?1677:?public?class?OriginalValuesDictionary?:?Dictionary<string,?Object>?1678:?{
?1679:?????public?OriginalValuesDictionary()?{?}
?1680:
?1681:?????protected?OriginalValuesDictionary(SerializationInfo?info,
?1682:????????????????????????????????????????StreamingContext?ctx)?
?1683:?????????:?base(info,?ctx)
?1684:?????{?}
?1685:?}
?
最后,ExtendedPropertiesDictionary 類
?1690:?public?class?ExtendedPropertiesDictionary?:?Dictionary<string,?Object>?1691:?{
?1692:?????public?ExtendedPropertiesDictionary()?{?}
?1693:
?1694:?????protected?ExtendedPropertiesDictionary(SerializationInfo?info,?
?1695:????????????????????????????????????????????StreamingContext?ctx)?
?1696:?????????:?base(info,?ctx)
?1697:?????{?}
?1698:?}
?
事件的處理
?
由于在進行二進制序列化的時候不會序列化事件的處理,所以,在反序列化之后,我們可以通過 OnDeserialized? 方法來執行一些我們自己的代碼完成這個工作。
為了給實體增加這些工作,我們可以在模板中找到 OnDeserializedMethod? 方法,然后增加三種重要的事件處理:
復雜類型事件處理
雙向連接的集合屬性的事件處理
級聯刪除的事件處理
?
將原來的 OnDeserializedMethod 方法直接用下面的替換掉
?
[OnDeserialized]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的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c#启动单个程序(互斥机制)
- 下一篇: 褥园连三个字怎么取水果店名?