我将EF核心用作ORM,可以将我的ES事件作为CRMS应用程序的读取端播放到该ORM。
我创建了一个新功能,需要对投影及其显示方式进行一些修改。我希望放弃当前的读取模型,并重新投影流以重建模型。
性能一直很差,因为每次我创建一个新的上下文并将其持久化时,都会遍历事件;
foreach (var event in events)
{
using (var scope = _container.BeginScope('projection-scope'))
using (var dbContext = scope.Resolve<MyDbContext>())
{
await scope.Resolve<IMediator>().Publish(event);
await context.SaveChangesAsync();
}
}
我正在使用DI容器将持久性调用保持在处理程序之外,以尝试对投影进行批处理并帮助提高性能,但是遇到了越来越大的困难,包括附加的实体,关系和其他SQL问题。
这是一种合理的策略,可以在EF上下文中进行多个操作,还是放弃ORM并寻求直接SQL方法(也许使用dapper)更好?
答案 0 :(得分:0)
在处理大量事件时,应考虑对事件流进行分区以并行创建投影。您可以基于AggregateId对流进行分区,以允许更新在Aggregate中串行处理。根据当前的吞吐量和所需的吞吐量,您应该能够对流进行分区以满足您的要求。
此外,由于您使用的是事件源,因此我想说EF从逻辑的角度来看是过大的,并且肯定会使您从性能的角度出发。您实际上只需要一种基于事件更新数据库的方法。在这种情况下,简单的ADO.NET就足够了,大概是调用存储过程。为了避免手写所有这些代码,您可以使用t4模板或您选择的其他生成器来生成它。