2014-10-23 2 views
0

Я хочу кэшировать объекты, чтобы избежать взаимодействия с базами данных, где это возможно. Когда я делаю что-то вроде:Кэширование сущностей - Как избежать Объект сущности не может ссылаться на несколько экземпляров IEntityChangeTracker

public IList<Website> Get() 
{ 
    //The `_cacheManager.Get` just retrieves the object from an `ObjectCache` instance based on key. 
    return _cacheManager.Get(CcCacheWebsiteAll,() => _websiteRepository.Table.ToList()); 
} 

Я бегу в проблемы при получении значения из кэша и назначения его на новый объект, который требует экземпляр этого типа.

Например:

var store = new Store(); 
store.Name = "something"; 
store.Website = _websiteService.Get().FirstOrDefault(); 
_storeService.Insert(store); 

//Where _storeService.Insert(store) is: 

public void InsertStore(Store store) 
{ 
    _storeRepository.Insert(store); //THIS will raise the error 
} 

Я бы подумал, что вызов ToList() по методу Get() бы бросить экземпляры в новый список и остановить этот вопрос, но я не нахожу это при тестировании.

Есть ли у кого-нибудь предложения?

Примечание. Чтобы убедиться, что у меня есть только один контекст, я отключил кеширование, и все работает должным образом.

Редактировать

Магазин Услуги CTOR:

public StoreService(IRepository<Store> storeRepository) 
{ 
    _storeRepository = storeRepository; 
} 

Сайт Сервис CTOR:

public WebsiteService(IRepository<Website> websiteRepository) 
{ 
    _websiteRepository= websiteRepository; 
} 
+0

Ваш '_websiteRepository' - это тот же экземпляр, что и ваш' _storeRepository'? – Maarten

+0

Нет, они находятся в разных службах. В принципе, каждый из них является 'IRepository ', 'IRepository ', поэтому это оболочка для EF. Я предполагаю, что, поскольку вы спросили об этом, 'ToList()' должен сортировать мою проблему? Если я знаю, что это должно сделать это, я сосредоточу свои усилия в другом месте. – webnoob

+0

Вы можете использовать '.ToList()', но это не мешает dbcontext отслеживать ваш экземпляр. Вы должны отделить его, чтобы dbcontext остановил его отслеживание, и что еще более важно, другой dbcontext может начать отслеживать его. Я также думаю, что вы не должны '.Insert (...)' it, но просто присоедините экземпляр к другому dbcontext. – Maarten

ответ

1

Вы сказали, у вас есть два контекста. Если вы используете один контекст (разрешаете его контекстом A) для загрузки вашего объекта, то этот объект отслеживается контекстом A. Вы не можете использовать этот экземпляр с другим контекстом (контекст B). Таким образом, вам нужно отделить вашу сущность от контекста A и прикрепить свою сущность к контексту B.

Метод отсоединения/прикрепления сущностей из/в контексты немного изменился с версиями Entity Framework, но для EF6 я думаю this article и this SO question описывает это довольно хорошо.

Смежные вопросы