【发布时间】:2020-07-23 02:57:43
【问题描述】:
使用实体框架异步执行对 Web api 的查询存在问题。 一般视图,例如请求发送到 API,ActionFilter 捕获请求到控制器的功能,使用响应键发送到客户端状态 ok,执行请求异步并在 SignalR 发送数据后。 ActionFilter 像这样开始异步执行:
HostingEnvironment.QueueBackgroundWorkItem(async (ct) =>
{
var response = await actionContext.ActionDescriptor.ExecuteAsync(actionContext.ControllerContext,
actionContext.ActionArguments, ct);
var data = new JavaScriptSerializer().Serialize(response);
await connectionContext.Connection.Send(connectionId, $"{requestKey};{data}");
});
控制器:
[HttpPost]
[Route("")]
public ICollection<TradeAccountModel> GetAll()
{
using (var ls = _lifetimeScope.BeginLifetimeScope())
{
return _tradeAccountService.GetAll();
}
}
服务:
public ICollection<TradeAccountModel> GetAll()
{
using (_tradeAccountRepository.BeginTransaction())
{
return _tradeAccountRepository.Get().Select(acc => acc.ToModel());
}
}
Respository 使用 UOW 模式。 并且当存储库尝试从 DB 获取数据时出现错误:System.InvalidOperationException: The operation cannot be completed because the DbContext has been released.
TDataRepository包含常用操作并扩展BaseDataRespository,如GetById等
public interface ITradeRepository: ITDataRepository<TradeAccount>
{
}
internal class TradeRepository : T1DataRepository<TradeAccount>,
ITradeRepository
{
}
IEnumerable<TEntity> ITDataRepository<TEntity>.Get()
{
return base.Get<TEntity>();
}
BaseDataRespository 有 BeginTransaction 方法
public IDisposable BeginTransaction()
{
if (_scope == null)
{
_scope = new TransactionScope(
TransactionScopeOption.Required,
new TransactionOptions()
{
IsolationLevel = IsolationLevel.ReadCommitted,
Timeout = TimeSpan.FromSeconds(300)
},
TransactionScopeAsyncFlowOption.Enabled);
}
return _scope;
}
上下文由 BaseDataRespository 创建
private TransactionScope _scope;
private readonly Lazy<DataContext> _contextFactory;
private DataContext Context => _contextFactory.Value;
public BaseDataRepository()
{
_contextFactory = new Lazy<DataContext>(()=>
{
var ctx = CreateContext();
ctx.FireBuild += Build;
return ctx;
});
}
【问题讨论】:
-
能发一下
_tradeAccountRepository的实现吗? -
是的,我已经编辑过帖子
-
我不明白你为什么需要使用
QueueBackgroundWorkItem。很可能它会导致你得到异常。因为您在操作过滤器中,并且您正在尝试执行操作结果手动操作,但是当 BackgroundWorker 运行您的代码时,该操作可能已经完成。 -
我要问和@Eldar 一样的问题。您是否正在执行动作过滤器中的另一个动作?
-
因为请求多,计算时间长
标签: c# asp.net entity-framework asynchronous action-filter