【发布时间】:2011-12-02 11:33:19
【问题描述】:
我正在尝试为实体实现缓存机制。为了正确无缝地使用实体与缓存,我需要先将实体从当前上下文中分离出来,然后再将其放入缓存中,并在我从缓存中获取它时将其附加回新上下文。 (我的上下文生命周期是每个 http 请求)
要求是-
- 在实体分离时,不应删除与其关联的所有导航属性(我已经填充)。
- 如果我愿意,我可以更新缓存的项目(因此正确地将它们附加到新的上下文很重要)。
这是我创建 EntityCache 类的尝试——(这里的 ServerCache 是将对象推送到 ASP.NET 缓存的包装类)
public static class EntityCache
{
private static DbContext context
{
get
{
return (DbContext)HttpContext.Current.Items[ObjectKeys.ContextRequestItemKey];
}
}
private static void Detach(object entity)
{
var trackedEntity = entity as IEntityWithChangeTracker;
trackedEntity.SetChangeTracker(null);
((IObjectContextAdapter)context).ObjectContext.Detach(entity);
}
private static void Attach(object entity)
{
((IObjectContextAdapter)context).ObjectContext.Attach((IEntityWithKey)entity);
}
public static void Remove(string key)
{
ServerCache.Remove(key);
}
public static object Get(string key)
{
object output = ServerCache.Get(key);
if (output != null)
Attach(output);
return output;
}
public static void ShortCache(String key, object data)
{
if (data != null)
{
Detach(data);
ServerCache.ShortCache(key, data);
}
}
public static void LongCache(String key, object data)
{
if (data != null)
{
Detach(data);
ServerCache.LongCache(key, data);
}
}
}
当我将一个实体放入缓存中时,它的类型是 DynamicProxy 而不是真正的类。
附加根本不起作用 - 我得到一个异常,我无法将 Dynamic_{blahblah} 类型的对象设置为 IEntityWithKey。
我刚刚在网上看到了这些附加和分离的示例并进行了尝试,我对这里的附加/分离方法的任何新实现持开放态度。
谢谢。
跟进问题 -
context.Entry(entity).State = EntityState.Detached;
有效,但将所有加载的导航属性设为 NULL,我们如何让它保留导航属性,而不是在脱离上下文时用 NULL 替换(或丢失)它们。
【问题讨论】:
-
整个问题没有问号是正常的吗? :)
-
更多的是——我在这里做错了什么,因此标题为“如何正确地做”,以为很清楚——但会添加一个“?”下次:)
-
删除演员表到
IEntityWithKey,你不需要它,因为ObjectContext.Attach接受object。如果您希望“真实”类关闭创建代理的所有内容(延迟加载、使用代理进行更改跟踪) - 包括它们可能带来的好处。我认为您不能将实体作为成员或通过代理中的方法检索,因为代理 inherits 来自实体。因此,代理IS 实体而不HAVE 实体。但是您会遇到冲突,因为您显然希望您的实体实现IEntityWithChangeTracker。 -
我不明白的另一件事是为什么要将上下文和缓存联系得如此紧密?在某些情况下——尤其是在 Web 应用程序中,它是大多数 = 大多数 GET 请求——您将从数据库中加载根本不附加到上下文的实体(使用
NoTracking选项),所以您不需要分离它们。另一方面,当您从缓存中检索实体时,为什么总是想将它们附加到上下文中?附加主要用于更改跟踪。但是,当您可以从缓存中提供 GET 请求时,为什么要更改跟踪或上下文呢? -
谢谢,我同意我不需要每次从缓存中获取它时都附加它,只有在我需要更新缓存的实体时才需要它。但是附加性能会受到影响吗?为什么我不应该每次都附上?同样对于您的第一条评论,我确实需要延迟加载、更改跟踪等,并且不想关闭“创建代理的所有内容”
标签: c# asp.net asp.net-mvc-3 entity-framework entity-framework-4.1