C# 将EF DatabaseContext注入自定义ScopedService
在我看来,作用域服务内注入的EF的性能非常低 在这种情况下,我很有可能错误地使用EF,但我无法找到正确的描述/文档说明如何在这种情况下使用EF(将其注入自定义托管服务) 在EasyRabbit/startup.cs(配置服务)中注册了以下服务:C# 将EF DatabaseContext注入自定义ScopedService,c#,asp.net-core-2.0,ef-core-2.0,C#,Asp.net Core 2.0,Ef Core 2.0,在我看来,作用域服务内注入的EF的性能非常低 在这种情况下,我很有可能错误地使用EF,但我无法找到正确的描述/文档说明如何在这种情况下使用EF(将其注入自定义托管服务) 在EasyRabbit/startup.cs(配置服务)中注册了以下服务: // db services.AddDbContext<ApplicationDbContext>(options => { options.UseSqlServer("Server=localhost; Database=Ra
// db
services.AddDbContext<ApplicationDbContext>(options =>
{
options.UseSqlServer("Server=localhost; Database=RabbitTest; MultipleActiveResultSets=true; User ID=sa; Password=Admin1234");
});
// default REST Api
services.AddMvc();
// Configuration for Rabbit connector
services.Configure<RabbitConfig>(Configuration.GetSection("RabbitConfig"));
// Rabbit Connector
services.AddSingleton<RabbitConnector>();
// Subscriber which listens if some new message arrives
services.AddSingleton<IHostedService, GenericHostedSubscriber<CalculatorInputs>>();
// Every arival message is then processed in following scope
// ApplicationDbContext dbContext is injected into this RabbitSubscribers.Adder
services.AddScoped<IScopedProcessingService<CalculatorInputs>, RabbitSubscribers.Adder>();
整个代码可以在
谢谢
复制步骤
编辑: 以下是当前测量的性能:
情景5、6。他们将adder.cs作为作用域服务嗯,ORM总是比较慢。在本例中,您只需插入一条记录。通过创建一个对象并将其添加到上下文中,您将产生大量开销。我建议您创建一个存储过程,将其作为函数插入并导入到上下文中。我怀疑这会大大加快速度。另一种选择是每隔一段时间收集批处理并进行大容量保存,以尽量减少对数据库的调用次数。我没想到会这么慢(比direct sql insert慢22倍)。几分钟前,我试图改变代码,而不是注入db上下文,我直接在HandleMessageAsync方法中使用EF上下文,平均性能提高到230条消息/秒。仍然比直接插入慢5倍,但比注入的EFWell快5倍,注入过程也会产生开销。看起来,
Adder
可能是一个单例。考虑到您当前的设计,我建议您:将Adder
设置为单例(如果可能的话),并继续添加到HandleMessageAsync
的上下文中,但在收集到100个Calculation
对象之前,不要调用SaveChangesSync
。否则,使用导入的函数。
namespace EasyRabbit.RabbitSubscribers
{
public class Adder : IScopedProcessingService<CalculatorInputs>
{
private ILogger<Adder> _logger;
private ApplicationDbContext _db;
public Adder(ApplicationDbContext dbContext, ILogger<Adder> logger)
{
_logger = logger;
_db = dbContext;
}
public async Task HandleMessageAsync(CalculatorInputs message)
{
Console.WriteLine($"Calculator: [{message.FirstNumber}] + [{message.SecondNumber}] = {message.FirstNumber + message.SecondNumber}");
await _db.Calculations.AddAsync(new Calculation()
{
FirstNumber = message.FirstNumber,
SecondNumber = message.SecondNumber,
Result = message.FirstNumber + message.SecondNumber
});
await _db.SaveChangesAsync();
}
}
}
public static class DB
{
private static string _connectionString = "Server=localhost; Database=RabbitTest; MultipleActiveResultSets=true; User ID=sa; Password=Admin1234";
public static void AddRecord(MyDBObject myDBObject)
{
using (SqlConnection con = new SqlConnection(_connectionString))
{
using (SqlCommand cmd = new SqlCommand("insert into test (FirstNumber, SecondNumber, Result) values (@FirstNumber, @SecondNumber, @Result)", con))
{
cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue("@FirstNumber", myDBObject.FirstNumber);
cmd.Parameters.AddWithValue("@SecondNumber", myDBObject.SecondNumber);
cmd.Parameters.AddWithValue("@Result", myDBObject.Result);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}
}
}
}
public class MyDBObject
{
public int FirstNumber { get; set; }
public int SecondNumber { get; set; }
public int Result { get; set; }
}