Entity framework core EntityFrameworkCore Task.WhenAll()在上一个操作完成之前,在此上下文上启动了第二个操作
我想从数据库中读取数据。为此,我创建了一个查询和queryhandler类 质问者Entity framework core EntityFrameworkCore Task.WhenAll()在上一个操作完成之前,在此上下文上启动了第二个操作,entity-framework-core,asp.net-core-3.0,Entity Framework Core,Asp.net Core 3.0,我想从数据库中读取数据。为此,我创建了一个查询和queryhandler类 质问者 public class OrderGetQueryHandler: IQueryHandler<OrderGetQuery, OrderDTO> { private readonly GoodWillWebDbContext _context; private readonly IQueryDispatcher _queryDispatcher;
public class OrderGetQueryHandler: IQueryHandler<OrderGetQuery, OrderDTO>
{
private readonly GoodWillWebDbContext _context;
private readonly IQueryDispatcher _queryDispatcher;
public OrderGetQueryHandler(GoodWillWebDbContext context, IQueryDispatcher queryDispatcher)
{
_context = context;
_queryDispatcher = queryDispatcher;
}
private bool CheckPartnerBlock(BlockTypes blockType, decimal debtOverdue, bool payOff)
{
if (blockType == BlockTypes.Block)
return true;
if (blockType == BlockTypes.NotBlock)
return false;
if (blockType == BlockTypes.PreliminaryPayment)
return payOff;
return debtOverdue <= 0;
}
public async Task<OrderDTO> HandleAsync(OrderGetQuery query)
{
var order = await _context.Orders.FindAsync(query.OrderID);
if (order != null)
{
var getCustomerTask = _context.Partners.FindAsync(order.CustomerID).AsTask();
var getCuratorTask = _context.Users.FindAsync(order.CuratorID).AsTask();
var getPaymentTask = _context.Payments.OrderByDescending(x => x.PaymentID).FirstOrDefaultAsync(x => x.CustomerID == order.CustomerID);
var getOrderLinesTask =
_queryDispatcher.HandleAsync<OrderLinesGetQuery, OrderLineDTO[]>(
new OrderLinesGetQuery(query.OrderID));
await Task.WhenAll(getCustomerTask, getCuratorTask, getOrderLinesTask, getPaymentTask);
var priceRange = await _context.PriceRanges.FindAsync(getCustomerTask.Result.PriceRangeID);
return new OrderDTO
(
order.OrderID,
getCustomerTask.Result.Name,
getOrderLinesTask.Result,
order.CustomerID,
order.OrderStateID,
order.CanDelete,
order.CreationDate,
getPaymentTask.Result.DebtBank,
getPaymentTask.Result.DebtOverdue,
this.CheckPartnerBlock(getCustomerTask.Result.BlockTypeID, getPaymentTask.Result.DebtOverdue, order.PayOff),
priceRange.Name,
order.ReservationDate,
Mapper.Convert<DeliveryInfoDTO, BaseEntities.Entities.Sales.Order>(order)
);
}
throw new NullReferenceException();
}
}
公共类OrderGetQueryHandler:IQueryHandler
{
私有只读GoodWillWebDbContext\u context;
专用只读IQueryDispatcher\u queryDispatcher;
public OrderGetQueryHandler(GoodWillWebDbContext上下文,IQueryDispatcher queryDispatcher)
{
_上下文=上下文;
_queryDispatcher=queryDispatcher;
}
私人bool CheckPartnerBlock(BlockTypes blockType、十进制过期债务、bool支付)
{
if(blockType==BlockTypes.Block)
返回true;
if(blockType==BlockTypes.NotBlock)
返回false;
if(blockType==BlockTypes.PreiminaryPayment)
回报;
返回过期债务x.PaymentID).FirstOrDefaultAsync(x=>x.CustomerID==order.CustomerID);
var getOrderLinesTask=
_queryDispatcher.HandleAsync(
新OrderLinesGetQuery(query.OrderID));
等待任务。whalll(getCustomerTask、getCuratorTask、getOrderLinesTask、getPaymentTask);
var priceRange=wait_context.PriceRanges.FindAsync(getCustomerTask.Result.PriceRangeID);
将新订单返回到
(
order.OrderID,
getCustomerTask.Result.Name,
getOrderLinesTask.Result,
order.CustomerID,
order.OrderStateID,
坎德莱特勋章,
创建日期,
getPaymentTask.Result.DebtBank,
getPaymentTask.Result.Debt过期,
this.CheckPartnerBlock(getCustomerTask.Result.BlockTypeID、getPaymentTask.Result.DebtOverside、order.PayOff),
priceRange.Name,
order.ReservationDate,
Mapper.Convert(顺序)
);
}
抛出新的NullReferenceException();
}
}
我在ASP.NET WEB应用程序中使用的这个查询句柄。我的创业班是
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
string connection = Configuration.GetConnectionString("DefaultConnection");
services.AddDbContext<GoodWillWebDbContext>(options =>
options.UseSqlServer(connection), ServiceLifetime.Transient);
services.AddScoped<IQueryHandler<OrdersGetQuery, BaseEntities.DTO.Sales.Order.OrderDTO[]>, OrdersGetQueryHandler>();
services.AddScoped<IQueryHandler<OrderGetQuery, Sales.Queries.DTO.Order.OrderDTO>, OrderGetQueryHandler>();
services.AddScoped<ICommandDispatcher, CommandDispatcher>();
services.AddScoped<IQueryDispatcher, QueryDispatcher>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
公共类启动
{
公共启动(IConfiguration配置)
{
配置=配置;
}
公共IConfiguration配置{get;}
public void配置服务(IServiceCollection服务)
{
services.AddControllers();
字符串连接=配置.GetConnectionString(“DefaultConnection”);
services.AddDbContext(选项=>
options.UseSqlServer(连接),ServiceLifetime.Transient);
services.addScope();
services.addScope();
services.addScope();
services.addScope();
}
//此方法由运行时调用。请使用此方法配置HTTP请求管道。
public void配置(IApplicationBuilder应用程序、IWebHostEnvironment环境)
{
if(env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(端点=>
{
endpoints.MapControllers();
});
}
}
我为我的上下文设置了ServiceLifetime.Transient,但仍然得到一个异常:InvalidOperationException在上一个操作完成之前在此上下文上启动的第二个操作
怎么了?您似乎在上下文中运行多个操作,而不等待前面的操作结束,而EF不喜欢:
var getCustomerTask = _context.Partners.FindAsync(order.CustomerID).AsTask();
var getCuratorTask = _context.Users.FindAsync(order.CuratorID).AsTask();
var getPaymentTask = _context.Payments.OrderByDescending(x => x.PaymentID).FirstOrDefaultAsync(x => x.CustomerID == order.CustomerID);
使这些呼叫同步或使用
wait
关键字 您似乎正在上下文上运行多个操作,而不等待前面的操作结束,而EF不喜欢:
var getCustomerTask = _context.Partners.FindAsync(order.CustomerID).AsTask();
var getCuratorTask = _context.Users.FindAsync(order.CuratorID).AsTask();
var getPaymentTask = _context.Payments.OrderByDescending(x => x.PaymentID).FirstOrDefaultAsync(x => x.CustomerID == order.CustomerID);
使这些呼叫同步或使用wait
关键字