【发布时间】:2014-10-23 20:37:28
【问题描述】:
我想缓存我的实体以尽可能避免数据库交互。当我做类似的事情时:
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
}
我原以为在 Get() 方法上调用 ToList() 会将实例放入一个新列表并停止问题,但我在测试时没有发现这一点。
有人有什么建议吗?
注意:为了确保我只有一个上下文,我禁用了缓存并且一切都按预期工作。
编辑
商店服务总监:
public StoreService(IRepository<Store> storeRepository)
{
_storeRepository = storeRepository;
}
网站服务总监:
public WebsiteService(IRepository<Website> websiteRepository)
{
_websiteRepository= websiteRepository;
}
【问题讨论】:
-
您的
_websiteRepository与您的_storeRepository是同一个实例? -
不,它们在不同的服务中。基本上,每个都是
IRepository<Website>, 'IRepository` 所以它是 EF 东西的包装器。我假设因为你问过, ToList()应该解决我的问题?如果我知道应该这样做,我会将精力集中在其他地方。 -
您可以使用
.ToList(),但这不会阻止 dbcontext 跟踪您的实例。您必须将其分离,以便 dbcontext 停止跟踪它,更重要的是,另一个 dbcontext 可以开始跟踪它。我也认为你不应该.Insert(...)它,而是简单地将实例附加到另一个 dbcontext。 -
哦!它只是保留对列表中对象的引用而不是实际副本吗?
-
是的,dbcontext 引用了实例。调用
.ToList()不会删除该引用。
标签: c# asp.net-mvc entity-framework entity-framework-6