我正在try 实现实体的缓存机制.为了正确且无缝地将实体与缓存一起使用,我需要在将实体放入缓存之前将其从当前上下文中分离出来,并在从缓存中获取新上下文时将其附加回新上下文.(我的上下文生存期是针对每个http请求的)

有关规定是-

  1. 分离实体时,不应删除与其关联的所有导航属性(我已经填充了这些属性).
  2. 如果需要,我可以更新缓存的项目(因此正确地将它们附加到新上下文非常重要).

这是我try 创建一个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}to IEntityWithKey的对象大小写为case.

我刚刚在网上看到了这些attach和detach的示例,并try 了它们,我对这里attach/detach方法的任何新实现都持开放态度.

谢谢.

跟进问题-

context.Entry(entity).State = EntityState.Detached;

工作,但是使所有加载的导航属性都为空,那么当我们从上下文中分离时,如何使它保留导航属性而不用空替换(或丢失)它们呢?

推荐答案

IEntityWithKey是其他类型实体的接口.它适用于"大"实体.例如EntityObject实现这个接口.这些实体不被视为POCO,也不受DbContext API的支持.

如果你想使用IEntityWithKey,你的类必须实现它——这不是自动发生的事情.

正确连接DbContext API应为:

dbContext.Set(typeof(entity)).Attach(entity); 

希望这也能奏效:

dbContext.Entry(entity).State = EntityState.Unchanged;

使用DbContext API进行正确的分离应为:

dbContext.Entry(entity).State = EntityState.Detached;

此外,您最好使用泛型方法,而不是object个.

Asp.net相关问答推荐

Reaction-Native SignalR连接在调试模式下工作,在释放模式下失败

如何从 JavaScript 调用 C# 函数?

ASP .Net Web API 将图像下载为二进制

未知的网络方法.参数名称:methodName

使用 JavaScript 更改 ASP.NET 标签的可见性

如何使用 app_GlobalResource 或 app_LocalResource?

尽管安装了 AspNetCoreModule,但在 IIS 中运行 ASP.NET Core 应用程序时出现 0x8007000d 错误 500.19

实体框架:如何解决外键约束可能导致循环或多个级联路径?

IIS Express - 增加内存限制

如何在 ASP.NET 中获取原始请求正文?

通过 ASP.NET/C# 使用 Plupload

由 UpdatePanel 内 GridView 内的 LinkBut​​ton 触发的完整回发

将字典绑定到中继器

主机与 DnsSafeHost

将Bundle 包添加到现有的 ASP.NET Webforms 解决方案

在 ASP.NET Web API 2 中禁用 *all* 异常处理(为我自己腾出空间)?

在.net的内存数据库中

RegisterStartupScript 不适用于 ScriptManager、Updatepanel.这是为什么?

无法使用 ip:port 访问 WEB API,但可以在 VS 调试模式下使用 localhost:port

ASP.NET MVC2/3 中runAllManagedModulesForAllRequests的正确用法是什么?