在 EF4.1 中正确地从上下文附加和分离实体 [英] Attaching and detaching entities from context correctly in EF4.1

查看:16
本文介绍了在 EF4.1 中正确地从上下文附加和分离实体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to implement caching mechanism for entities. And to use the entities correctly and seamlessly with the caching i need to detach the entity from the current context before i put it in a cache and attach it back the the new context when i get it from the cache. (My context lifetime is per http request)

要求是 -

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

这是我尝试创建一个 EntityCache 类 -(ServerCache 是我将对象推送到 ASP.NET 缓存的包装类)

This is my attempt at creating an EntityCache class - (ServerCache here is my wrapper class that pushes the object to ASP.NET cache)

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 而不是真正的类.

When i put an entity in the cache it is of type DynamicProxy and NOT the real class.

附加根本不起作用 - 我得到一个例外,我不能将 Dynamic_{blahblah} 类型的对象分配给 IEntityWithKey.

Attaching doesnt work at all - i get an exception that i cannot case object that is of type Dynamic_{blahblah} to IEntityWithKey.

我刚刚在网上看到了这些附加和分离的例子并尝试了它们,我对这里的附加/分离方法的任何新实现持开放态度.

I just saw these examples of attach and detach online and tried them, I am open to any new implementation of the Attach/Detach methods here.

谢谢.

跟进问题 -

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

有效,但使所有加载的导航属性为 NULL,我们如何使其保持导航属性,并且在我们从上下文中分离时不将它们替换(或丢失)为 NULL.

Works, but makes all the navigational properties that are loaded NULL, how do we make it keep the navigational properties and NOT replace(or lose) them with NULL when we detach from context.

推荐答案

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

IEntityWithKey is interface for other types of entities. It is for "big" entities. For example EntityObject implement this interface. These entities are not considered as POCO and are not supported by DbContext API.

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

If you want to use IEntityWithKey your classes must implement it - it is not something that would happen automatically.

使用 DbContext API 正确附加应该是:

Correct attaching with DbContext API should be:

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

希望这也能奏效:

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

使用 DbContext API 正确分离应该是:

Correct detaching with DbContext API should be:

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

此外,最好使用通用方法而不是object.

Also it is better to you generic methods instead of object.

这篇关于在 EF4.1 中正确地从上下文附加和分离实体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆