0

我想利用新的 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>
4

1 回答 1

0

经过更多研究后,我无法找到在使用 Windows Azure 缓存服务时将 Linq 存储到 Sql 对象的方法。我遇到了与其他进程外会话机制(如基于 SQL Server 的会话状态)相同的问题。对我来说最好的解决方案是使用类似于本文中的 SessionHelper 对象。我将对象存储到会话中的页面加载中的行更改为:

SessionHelper.Set("Parent", newParent);

最后,我的问题与 Windows Azure 缓存无关,但与stackoverflow 上的这篇文章非常相似

于 2013-09-11T17:39:44.513 回答