如何使用 Windows Azure Cache Service (预览版) 在会话中存储 Linq to Sql 对象
本文关键字:会话 存储 Linq 对象 Sql to Azure Windows 何使用 Cache Service | 更新日期: 2023-09-27 18:30:16
>我想利用新的Windows Azure Cache Service(预览版),并且能够按照本文使用Session成功地存储和检索缓存中的内容。不幸的是,我们将 Linq to Sql 对象存储在 Session 中,目前我们无法更改它。尝试使用 Azure 缓存服务在会话中存储此类对象时,出现以下错误:
键入 'System.Data.Linq.EntitySet'1[cachetest.子]'不能序列化。请考虑使用 DataContractAttribute 属性标记它,并使用 DataMemberAttribute 属性标记要序列化的所有成员。 如果类型是集合,请考虑使用 CollectionDataContractAttribute 标记它。
我对数据上下文使用了"单向"序列化模式,因此所有声明都已使用"DataContract"和"DataMember"属性进行修饰(请参阅下面的代码示例)。
我已经研究了使用类似于本文和这篇关于堆栈溢出的文章的自定义序列化程序,但收到了与本文末尾描述的确切错误匹配的错误,其中指出
缓存的 ASP.NET 提供程序不支持二进制或自定义序列化类型
由于自定义序列化程序不是一个选项,我还能如何使用Windows Azure Caching在会话中存储Linq to Sql对象(具有父子关系)?
我已经分解了说明以下问题的代码。
Linq DataContext:
<?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>
经过更多的研究,我无法找到一种在使用Windows Azure缓存服务时将Linq到SQL对象存储在会话中的方法。我遇到了其他进程外会话机制(如基于 SQL Server 的会话状态)的相同问题。对我来说,最好的解决方案是使用类似于本文中的 SessionHelper 对象。我将页面加载中将对象存储到会话中的行更改为:
SessionHelper.Set("Parent", newParent);
最后,我的问题与Windows Azure缓存并不特别相关,但与这篇关于stackoverflow的文章非常相似。