Я пытаюсь реализовать механизм кеширования для сущностей. А чтобы правильно и беспрепятственно использовать сущности с кешированием, мне нужно отсоединить сущность от текущего контекста, прежде чем я помещу ее в кеш, и прикреплю обратно к новому контексту, когда я получу его из кеша. (Время жизни моего контекста зависит от 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
. Если вы хотите, чтобы настоящий класс отключил все, что создает прокси (отложенная загрузка, отслеживание изменений с помощью прокси), включая их возможные преимущества. Я не думаю, что вы можете получить объект как член или методом от прокси, потому что прокси наследует от объекта. Итак, прокси ЯВЛЯЕТСЯ сущностью и не ИМЕЕТ сущность. Однако у вас будет конфликт, потому что вы, очевидно, ожидаете, что ваши объекты будут реализовыватьIEntityWithChangeTracker
. - person Slauma   schedule 07.10.2011NoTracking
), поэтому вам не нужно их отсоединять . А с другой стороны, почему вы всегда хотите присоединять сущности к контексту, когда извлекаете их из кеша? Прикрепление в основном предназначено для отслеживания изменений. Но если вы можете обслуживать GET-запрос из своего кеша, зачем вообще изменять отслеживание или контекст? - person Slauma   schedule 07.10.2011AttachTo
(но для этого также требуется имя набора сущностей в качестве дополнительного параметра). - person Slauma   schedule 07.10.2011