我正在尝试为实体实现缓存机制。为了在缓存中正确无缝地使用实体,我需要先将实体从当前上下文中分离出来,然后再将其放入缓存中,并在从缓存中获取实体时将其附加回新上下文。(我的上下文生存期为每个http请求)
要求是-
- 分离实体时,不应删除与其关联的所有导航属性(我已经填充了这些属性)
- 如果需要,我可以更新缓存项(因此正确地将它们附加到新上下文非常重要)
这是我创建EntityCache类的尝试-(ServerCache这里是我将对象推送到ASP.NET缓存的包装器类)
公共静态类EntityCache
{
私有静态DbContext上下文
{
收到
{
返回(DbContext)HttpContext.Current.Items[ObjectKeys.ContextRequestItemKey];
}
}
专用静态空心分离(对象实体)
{
var trackedEntity=实体作为IEntityWithChangeTracker;
SetChangeTracker(空);
((IObjectContextAdapter)context.ObjectContext.Detach(实体);
}
专用静态空心附着(对象实体)
{
((IObjectContextAdapter)context.ObjectContext.Attach((IEntityWithKey)实体);
}
公共静态无效删除(字符串键)
{
ServerCache.Remove(key);
}
公共静态对象Get(字符串键)
{
对象输出=ServerCache.Get(键);
if(输出!=null)
附加(输出);
返回输出;
}
公共静态void快捷缓存(字符串键、对象数据)
{
如果(数据!=null)
{
分离(数据);
快捷缓存(键、数据);
}
}
公共静态void LongCache(字符串键、对象数据)
{
如果(数据!=null)
{
分离(数据);
LongCache(键、数据);
}
}
}
当我将实体放入缓存时,它是DynamicProxy类型,而不是真正的类
附加根本不起作用-我得到一个异常,我无法将类型为Dynamic_{blahblah}的对象case到IEntityWithKey
我刚刚在网上看到了这些attach和detach的示例,并尝试了它们,我对这里attach/detach方法的任何新实现都持开放态度
多谢各位
跟进问题-
context.Entry(entity.State=EntityState.Detached;
可以工作,但会使加载的所有导航属性都为NULL,当我们从上下文分离时,如何使导航属性保持为NULL,而不替换(或丢失)为NULL
IEntityWithKey是其他类型实体的接口。它适用于“大”实体。例如EntityObject实现此接口。这些实体不被视为POCO,并且不受DbContextAPI支持
如果你想使用IEntityWithKey你的类必须实现它——这不是自动发生的事情
与DbContextAPI的正确连接应为:
dbContext.Set(typeof(entity)).Attach(entity);
希望这也能起作用:
dbContext.Entry(entity.State=EntityState.Unchanged;
使用DbContextAPI进行正确的分离应该是:
dbContext.Entry(entity.State=EntityState.Detached;
此外,最好使用泛型方法,而不是对象