MVC - 工作单元 - 重复记录问题

时间:2012-10-31 11:12:29

标签: asp.net asp.net-mvc unit-of-work

我正在处理这个项目,我们有一个保存实体的表单,在保存之前,我们通过检查数据库中实体的唯一属性来检查记录是否存在。

除了我们多次按下提交表单按钮的情况外,这种方法很好。在这种情况下,数据库检查不起作用,它会在数据库中创建记录的多个条目。

我认为这是应用程序的设计问题,但我是工作单元模式的新手,我无法理解为什么不工作。

这是我们在服务层上进行的检查:

    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实例?

1 个答案:

答案 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请求中创建两次或更多次没有任何害处。