我正在处理这个项目,我们有一个保存实体的表单,在保存之前,我们通过检查数据库中实体的唯一属性来检查记录是否存在。
除了我们多次按下提交表单按钮的情况外,这种方法很好。在这种情况下,数据库检查不起作用,它会在数据库中创建记录的多个条目。
我认为这是应用程序的设计问题,但我是工作单元模式的新手,我无法理解为什么不工作。
这是我们在服务层上进行的检查:
IEnumerable<Story> Stories = _unitOfWork.StoryRepository.Get(s => e.GUID.Equals(GUID));
if (Stories.Count() > 0)
{
_unitOfWork. StoryRepository.Insert(newStory);
_unitOfWork.Save();
}
任何人都可以帮助解决这个问题吗?
不过,我不是在基于javascript的解决方案之后,只是服务器端。由于
编辑: 该服务使用ninject并具有传递工作单元的构造函数:
private IUnitOfWork _unitOfWork;
public StoryService(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
我的UnitOfWork类声明为:
public class UnitOfWork : Disposable, IUnitOfWork
DatabaseFactory.cs:
public class DatabaseFactory : Disposable, IDatabaseFactory
{
private myContext _dataContext;
private readonly object _door = new object();
public myContext Get()
{
lock (_door)
{
return _dataContext ?? (_dataContext = new myContext());
}
}
protected override void DisposeCore()
{
if (_dataContext != null)
_dataContext.Dispose();
}
}
每次我调用Pluc建议的服务方法时,是否应该创建UnitOfWork实例?
答案 0 :(得分:0)
很可能,您过早地创建了自己的工作单元。你的工作单位应该是一个IDisposable enity,以便你可以在你想要的时候使用它,并在之后立即摆脱它。对于这种情况,使用语句变得非常好:
using(var unitOfWork = new UnitOfWork())
{
IEnumerable<Story> Stories = unitOfWork.StoryRepository.Get(s => e.GUID.Equals(GUID));
if (Stories.Count() > 0)
{
unitOfWork.StoryRepository.Insert(newStory);
unitOfWork.Save();
}
}
如果您的UnitOfWork很早就创建了,并且StoryRepository会在早期的其他场合使用,那么Stories就已经加载了。如果你单击提交两次,取决于页面加载速度,那么你有一个很好的竞争条件,如果来自请求#1的UnitOfWork在请求#2懒惰加载他之前没有保存他的上下文,那么这两个请求都会有完全相同的故事列表和条件将通过两者。
如果您根据需要创建UnitOfWork,它甚至不会加载Stories,因此,唯一的窗口是进行错误的条件测试,是.Get()存储库方法与您之间的0.001ms。 unitOfWork.Save()。
请始终牢记,UnitOfWork可以通过一次批量处理所有查询来优化您的数据访问。它不是数据缓存工具。创建它,使用它,转储它。在单个Web请求中创建两次或更多次没有任何害处。