我编写了一个WPF应用程序,但是我在刷新数据时遇到了问题,这些数据是从SQL Server数据库中提取的。
我使用StructureMap来注入依赖项,还管理DBContext的生命周期。这是我的StructureMap配置:
ObjectFactory.Container.Configure(cfg =>
{
cfg.For<IUnitOfWork>()
.LifecycleIs(new ThreadLocalStorageLifecycle())
.Use<DBContext>();
});
但是当我从另一个应用程序实例或直接从SQL Server编辑记录时,之前获取过该记录的客户端无法自行刷新并只显示未修改的数据。
我使用 .LifecycleIs(new ThreadLocalStorageLifecycle())在每个线程上使用不同的Context来清除EntityFramework的缓存,但它不起作用。
这是我的服务类:
public class DraftService : IDraftService
{
IUnitOfWork _uow;
IDbSet<Models.Draft> _draft;
public DraftService(IUnitOfWork uow)
{
_uow = uow;
_draft = _uow.Set<Models.Draft>();
}
public Models.Draft GetByID(long id)
{
return _draft.Find(id);
}
}
我使用的服务如下:
public class Draft
{
private IUnitOfWork _uow;
private IDraftService _draftService;
public Draft(IUnitOfWork uow, IDraftService draftService)
{
_uow = uow;
_draftService = draftService;
}
public async Task<Models.Draft> GetByID(long id)
{
return await Task.Run(() => _draftService.GetByID(id));
}
}
有什么问题?为什么它不刷新数据?
提前致谢。
答案 0 :(得分:2)
我认为结构图不是您的问题,您在跟踪实体时遇到问题。看一下这篇文章:http://www.entityframeworktutorial.net/change-tracking-in-entity-framework.aspx
这可能是通过以下代码解决的:
Models.Draft query = _draft.AsNoTracking().FirstOrDefault(r=>r.ID == id);
我希望它有所帮助。
实体框架中的更改跟踪 本节介绍实体框架如何跟踪实体的变化。
答案 1 :(得分:1)
编辑:经过一段时间的清醒,这就是发生的事情。
替换:return _draft.Find(id); // Find use the Cache if it can.
通过:return _draft.SingleOrDefault(x => x.id == id) // SingleOrDefault should Fetch from the database each time.
我的评论不够明确让我们来看看:
public class DraftService : IDraftService
{
IUnitOfWork _uow; <-- if this is disposed and _draft is accessed you'll get an error.
IDbSet<Models.Draft> _draft; <-- might be cached.
public DraftService(IUnitOfWork uow)
{
_uow = uow; <--- this context is always the same
_draft = _uow.Set<Models.Draft>();
}
public Models.Draft GetByID(long id)
{
return _draft.Find(id); <---- this will always use the cached context.
}
}
如果你让它看起来像这样。 你得到的问题要少得多。
public class DraftService : IDraftService
{
Container _ctn;
public DraftService(Container ctn)
{
_ctn= ctn;
}
public Models.Draft GetByID(long id)
{
using(var uow = _ctn.Resolve<IUnitOfWork>()){ // new fresh context. don't forget the AlwaysUnique.
return uow.Set<Draft>().Find(id); // should return the newer revision.
}}
}
如果您不想传递容器:
public class DraftService : IDraftService
{
IUnitOfWorkResolver _rslv;
public DraftService(IUnitOfWorkResolver rslv)
{
_rslv= rslv;
}
public Models.Draft GetByID(long id)
{
using(var uow = rslv.GetContext()){ // new fresh context. don't forget the AlwaysUnique.
return uow.Set<Draft>().Find(id); // should return the newer revision.
}}
}
public class UnitOfWorkResolver{
public IUnitOfWork GetContext(){
return new DBContext(); //or whatever you want you could use Container.Resolve<IUnitOFWork>() instead.
}
}
我没有放入IUnitOfWorkResolver,但你明白了......