我想利用新的 Windows Azure 缓存服务(预览版),并能够按照这篇文章使用 Session 成功地在缓存中存储和检索内容。不幸的是,我们将 Linq 存储到 Session 中的 Sql 对象,此时我们无法更改它。尝试使用 Azure 缓存服务将此类对象存储在 Session 中时,出现以下错误:
无法序列化类型“System.Data.Linq.EntitySet`1[cachetest.Child]”。考虑使用 DataContractAttribute 属性对其进行标记,并使用 DataMemberAttribute 属性标记您想要序列化的所有成员。如果该类型是一个集合,请考虑使用 CollectionDataContractAttribute 对其进行标记。
我为我的数据上下文使用了“单向”序列化模式,所以所有声明都已经用“DataContract”和“DataMember”属性修饰(参见下面的代码示例)。
我已经研究过使用类似于这篇文章和这篇关于 stackoverflow的文章的自定义序列化程序,但收到的错误与本文末尾描述的确切错误相匹配,其中指出
缓存的 ASP.NET 提供程序不支持二进制或自定义序列化类型
由于自定义序列化程序不是一个选项,我还能如何使用 Windows Azure 缓存在 Session 中将 Linq 存储到 Sql 对象(具有父子关系)?
我已经分解了说明以下问题的代码。
Linq 数据上下文:
<?xml version="1.0" encoding="utf-8"?><Database Class="TestModelDataContext" Serialization="Unidirectional" xmlns="http://schemas.microsoft.com/linqtosql/dbml/2007">
<Table Name="" Member="Parents">
<Type Name="Parent">
<Column Member="Name" Type="System.String" CanBeNull="false" />
<Column Member="ParentId" Type="System.Int32" IsPrimaryKey="true" CanBeNull="false" />
<Association Name="Parent_Child" Member="Childs" ThisKey="ParentId" OtherKey="ParentId" Type="Child" />
</Type>
</Table>
<Table Name="" Member="Childs">
<Type Name="Child">
<Column Member="Name" Type="System.String" CanBeNull="false" />
<Column Member="ChildId" Type="System.Int32" IsPrimaryKey="true" CanBeNull="false" />
<Column Member="ParentId" Type="System.Int32" CanBeNull="false" />
<Association Name="Parent_Child" Member="Parent" ThisKey="ParentId" OtherKey="ParentId" Type="Parent" IsForeignKey="true" />
</Type>
</Table>
</Database>
使用会话的页面:
namespace cachetest
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Parent newParent = new Parent { Name = "John", ParentId=1 };
Child child1 = new Child { ChildId = 1, Name="John Jr." };
Child child2 = new Child { ChildId = 2, Name="Betty" };
newParent.Childs.Add(child1);
newParent.Childs.Add(child2);
Session["parent"] = newParent;
}
}
}
Web.Config(删除敏感数据):
<?xml version="1.0"?>
<configuration>
<configSections>
<section name="dataCacheClients" type="Microsoft.ApplicationServer.Caching.DataCacheClientsSection, Microsoft.ApplicationServer.Caching.Core" allowLocation="true" allowDefinition="Everywhere"/>
<section name="cacheDiagnostics" type="Microsoft.ApplicationServer.Caching.AzureCommon.DiagnosticsConfigurationSection, Microsoft.ApplicationServer.Caching.AzureCommon" allowLocation="true" allowDefinition="Everywhere"/>
</configSections>
<connectionStrings>
</connectionStrings>
<system.web>
<compilation debug="true" targetFramework="4.5"/>
<httpRuntime/>
<sessionState mode="Custom" customProvider="AFCacheSessionStateProvider">
<providers>
<add name="AFCacheSessionStateProvider" type="Microsoft.Web.DistributedCache.DistributedCacheSessionStateStoreProvider, Microsoft.Web.DistributedCache" cacheName="default" dataCacheClientName="default" applicationName="AFCacheSessionState"/>
</providers>
</sessionState>
<pages controlRenderingCompatibilityVersion="4.0"/>
</system.web>
<dataCacheClients>
<dataCacheClient name="default">
<autoDiscover isEnabled="true" identifier="[cachename].cache.windows.net"/>
<securityProperties mode="Message" sslEnabled="false">
<messageSecurity authorizationInfo="[CacheKey]"/>
</securityProperties>
</dataCacheClient>
</dataCacheClients>
</configuration>