Я пытаюсь реализовать механизм кэширования для объектов. И чтобы использовать объекты правильно и плавно с кешированием, мне нужно отделить объект от текущего контекста, прежде чем я поместил его в кеш и приложил его обратно к новому контексту, когда я получу его из кеша. (Мое время жизни зависит от 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 и НЕ настоящий класс.
Прикрепление вообще не работает - я получаю исключение, которое не может иметь объект case, который имеет тип Dynamic_ {blahblah} для IEntityWithKey.
Я только что увидел эти примеры подключения и отсоединения в Интернете и попробовал их, я открыт для любой новой реализации методов Attach/Detach здесь.
Спасибо.
Последующий вопрос -
context.Entry(entity).State = EntityState.Detached;
Работает, но делает все навигационные свойства, которые загружаются NULL, как мы это делаем, сохраняем навигационные свойства и НЕ заменяем (или теряем) их с помощью NULL, когда мы отключаемся от контекста.