显然(并且很可能)我当前的UnitOfWork实现存在缺陷,因为我在同时进行多次调用时遇到连接错误。
例外:
底层提供程序在Open上失败。
内部异常:
连接未关闭。连接的当前状态是 连接。
这会在客户端产生HTTP 500响应。
UnitOfWork实施
public class ScopedUnitOfWork : IUnitOfWork
{
public Entities Context { get; set; }
public UnitOfWorkState State { get; set; }
public ScopedUnitOfWork(IEnvironmentInformationProvider environmentInformationProvider)
{
this.Context = new Entities(environmentInformationProvider.ConnectionString);
this.State = UnitOfWorkState.Initialized;
}
public UowScope GetScope()
{
this.State = UnitOfWorkState.Working;
return new UowScope(this);
}
public SaveResult Save()
{
if (this.State != UnitOfWorkState.Working)
throw new InvalidOperationException("Not allowed to save out of Scope. Request an UowScope instance by calling method GetScope().");
this.Context.SaveChanges();
this.State = UnitOfWorkState.Finished;
return new SaveResult(ResultCodes.Ok);
}
}
使用单个UowScope
可以解决问题,但鉴于目前的情况,这是不可能的,因为每个请求都是完全独立的。事实上每个请求都使用UoWScope
,但显然当UoW一次接收到多个呼叫时出错。
UoW是通过Unity IoC注入的,所以我认为它是一个有效的单身人士。
问题
有没有办法调整UoW,以便单独的高频请求不成问题?
最好是我解决这个服务器端,而不是客户端,任何提示?谢谢!
声明
我没有声称我完全理解UoW,所以我的实施可能需要改进,温柔:)。当然,任何改进都是受欢迎的!
更新
我知道--EF Context是一个UoW,我在Domain级别使用我的,以启用与功能相关的数据的事务处理。而且也是出于客户需求,我别无选择。
答案 0 :(得分:3)
您遇到的问题是,工作单元对象实际上是一个单独的单元,因为您的IoC框架会在应用程序的持续时间内保持它。这意味着您的上下文也在UoW中保持为单身。因此,您几乎肯定会对您的上下文进行多次并发调用,这将引发异常。
但是,我认为你误用了UoW应该做的事情的概念。 UoW用于为一组事务提供容器。例如,假设您有一个电子商务平台。当您创建订单时,您将在订单表中插入一行,然后作为同一交易的一部分,您还将在订单商品表中插入行,更新用户忠诚度积分等。所以您应该在一个单一内执行所有这些操作工作单位,承诺,然后销毁它。让IoC框架(在本例中为Unity)为每个会话创建您的工作单元。