我有以下对象:
[Serializable]
public class Module
{
[Key]
public int Id { get; set; }
public string ModuleName { get; set; }
public string FontAwesomeClass { get; set; }
}
[Serializable]
public class ModulosPorUsuario
{
[Key]
public int Id { get; set; }
public string Email { get; set; }
public virtual ICollection<Module> Modules{ get; set; }
}
我正在使用该方法缓存每个用户指定模块的特定密钥。
/// <summary>
/// Gets the modules activated for a user
/// </summary>
/// <param name="email">Email address of the user</param>
/// <returns>List of modules for the selected user</returns>
public static List<Models.ModulosPorUsuario> GetModulesForUser(string identityname)
{
/// It needs to be cached for every user because every user can have different modules enabled.
var cachekeyname = "ApplicationModulesPerUser|" + identityname;
IDatabase cache = CacheConnectionHelper.Connection.GetDatabase();
List<Models.ModulosPorUsuario> listOfModulesPerUser = new List<Models.ModulosPorUsuario>();
listOfModulesPerUser = (List<Models.ModulosPorUsuario>)cache.Get(cachekeyname);
if (listOfModulesPerUser == null)
{
listOfModulesPerUser = dbApp.ModulosPorUsuario.Where(p => p.Email == identityname).ToList();
cache.Set(cachekeyname, listOfModulesPerUser, TimeSpan.FromMinutes(SettingsHelper.CacheModuleNames));
return listOfModulesPerUser;
}
else
{
return listOfModulesPerUser;
}
}
第一次工作,当然是从数据库返回数据。 但第二次,(缓存上有一个对象),但模块列表为null:
http://screencast.com/t/OFB1vkvno
我也有来自stackexchange redis cache的这个辅助类:
public static class SampleStackExchangeRedisExtensions
{
public static T Get<T>(this IDatabase cache, string key)
{
return Deserialize<T>(cache.StringGet(key));
}
public static object Get(this IDatabase cache, string key)
{
return Deserialize<object>(cache.StringGet(key));
}
public static void Set(this IDatabase cache, string key, object value, TimeSpan expiration)
{
cache.StringSet(key, Serialize(value), expiration);
}
static byte[] Serialize(object o)
{
if (o == null)
{
return null;
}
BinaryFormatter binaryFormatter = new BinaryFormatter();
using (MemoryStream memoryStream = new MemoryStream())
{
binaryFormatter.Serialize(memoryStream, o);
byte[] objectDataAsStream = memoryStream.ToArray();
return objectDataAsStream;
}
}
static T Deserialize<T>(byte[] stream)
{
BinaryFormatter binaryFormatter = new BinaryFormatter();
if (stream == null)
return default(T);
using (MemoryStream memoryStream = new MemoryStream(stream))
{
T result = (T)binaryFormatter.Deserialize(memoryStream);
return result;
}
}
}
我知道由于SEED有相关数据:
#region Seed Modules
var module1 = new Module() { Id = 1, ModuleName = "Contabilidad", FontAwesomeClass = "fa-ambulance" };
var module2 = new Module() { Id = 2, ModuleName = "Recursos Humanos", FontAwesomeClass = "fa-heartbeat" };
var module3 = new Module() { Id = 3, ModuleName = "Inventario", FontAwesomeClass = "fa-anchor" };
var module4 = new Module() { Id = 4, ModuleName = "Produccion", FontAwesomeClass = "fa-binoculars" };
var module5 = new Module() { Id = 5, ModuleName = "Produccion", FontAwesomeClass = "fa-binoculars" };
var module6 = new Module() { Id = 6, ModuleName = "Ventas", FontAwesomeClass = "fa-coffee" };
var module7 = new Module() { Id = 7, ModuleName = "Compras", FontAwesomeClass = "fa-calendar-o" };
var module8 = new Module() { Id = 8, ModuleName = "Cotizaciones", FontAwesomeClass = "fa-building" };
context.Modulos.Add(module1);
context.Modulos.Add(module2);
context.Modulos.Add(module3);
context.Modulos.Add(module4);
context.Modulos.Add(module5);
context.Modulos.Add(module6);
context.Modulos.Add(module7);
context.Modulos.Add(module8);
context.SaveChanges();
#endregion
#region Seed ModulosPor Usuario
context.ModulosPorUsuario.Add(new ModulosPorUsuario()
{
Id=1,
Email = "companyadmin@mysaasapp.onmicrosoft.com",
Modules = new List<Module>() { module1, module2 }
});
context.ModulosPorUsuario.Add(new ModulosPorUsuario()
{
Id=2,
Email = "accountingadmin@mysaasapp.onmicrosoft.com",
Modules = new List<Module>() { module3, module5 }
});
context.ModulosPorUsuario.Add(new ModulosPorUsuario()
{
Id=3,
Email = "jayhamlin@mysaasapp.onmicrosoft.com",
Modules = new List<Module>() { module4, module6 }
});
context.ModulosPorUsuario.Add(new ModulosPorUsuario()
{
Id=4,
Email = "usuario1@mysaasapp.onmicrosoft.com",
Modules = new List<Module>() { module7, module7 }
});
context.SaveChanges();
#endregion
UPDATE1:
这是我第二次尝试获取缓存值时得到的错误:
mscorlib.dll中发生了'System.Runtime.Serialization.SerializationException'类型的异常但未在用户代码中处理
Additional information: Unable to find assembly 'EntityFrameworkDynamicProxies-Inspinia_MVC5, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
堆栈跟踪
at System.Runtime.Serialization.Formatters.Binary.BinaryAssemblyInfo.GetAssembly()
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.GetType(BinaryAssemblyInfo assemblyInfo, String name)
at System.Runtime.Serialization.Formatters.Binary.ObjectMap..ctor(String objectName, String[] memberNames, BinaryTypeEnum[] binaryTypeEnumA, Object[] typeInformationA, Int32[] memberAssemIds, ObjectReader objectReader, Int32 objectId, BinaryAssemblyInfo assemblyInfo, SizedArray assemIdToAssemblyTable)
at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadObjectWithMapTyped(BinaryObjectWithMapTyped record)
at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadObjectWithMapTyped(BinaryHeaderEnum binaryHeaderEnum)
答案 0 :(得分:2)
我相信您需要为此类型创建一个空构造函数(请参阅下面的代码段)并实例化您的集合。序列化引擎不会为你做这件事,它会期望实例化该集合。
此外,由于您的集合属性是接口而不是类,因此在尝试初始化此属性并添加项时,Serializer可能会感到困惑。
public class ModulosPorUsuario
{
// added this constructor
public ModulosPorUsuario()
{
this.Modules = new List<Module>();
}
[Key]
public int Id { get; set; }
public string Email { get; set; }
public virtual ICollection<Module> Modules { get; set; }
}
以为您在序列化之前初始化它,序列化程序在您反序列化时代表您实例化对象。
快乐编码。