C# 统计EF Core支持的标识系统中的查询数
我正在运行ASP.NET Core Identity UserManager和jazz,由EF Core stores支持。我最近在我的应用程序中遇到了一个错误,控制器端点导致对UserManager.UpdateSync的调用过多 因为我有一个WebApplicationFactory设置和一个UseInMemoryDatabase的集成测试。。。我想写一个集成/冒烟测试,如果控制器端点超出其查询预算,它会警告我 基本上,我很想写,但不能写这个测试:C# 统计EF Core支持的标识系统中的查询数,c#,asp.net-core,entity-framework-core,asp.net-core-identity,C#,Asp.net Core,Entity Framework Core,Asp.net Core Identity,我正在运行ASP.NET Core Identity UserManager和jazz,由EF Core stores支持。我最近在我的应用程序中遇到了一个错误,控制器端点导致对UserManager.UpdateSync的调用过多 因为我有一个WebApplicationFactory设置和一个UseInMemoryDatabase的集成测试。。。我想写一个集成/冒烟测试,如果控制器端点超出其查询预算,它会警告我 基本上,我很想写,但不能写这个测试: public class FooContr
public class FooControllerTests : IClassFixture<WebApplicationFactory>
{
private readonly WebApplicationFactory _factory;
public FooControllerTests(WebApplicationFactory factory)
{
_factory = factory;
}
[Fact]
public async Task Bar_WhenCalled_StaysWithinQueryBudget()
{
using var scope = _factory.Server.Host.Services.CreateScope();
var services = scope.ServiceProvider;
var dbContext = services.GetRequiredService<MyDbContext>();
var countBefore = dbContext.SomehowGetCurrentQueryCount(); // ??
var httpClient = _factory.CreateClient();
var _ = httpClient.PostAsJsonAsync("/foo/bar", new { data = "something" });
var countAfter = dbContext.SomehowGetCurrentQueryCount(); // ??
var budgetForEndpoint = 3;
Assert.True(countAfter - countBefore > budgetForEndpoint);
}
}
但重要的是精神:我想要一个冒烟测试来检查我将来是否不会犯同样的错误,是否有一个导致太多更新查询的bug
我尝试编写并将其添加到AddDbContext调用中,但似乎是通过AddEntityFrameworkStores添加的存储。。。与此隔离,因为从未调用过我的CommandCreating处理程序
如果查询通过Identity EF Core Stores运行,如何检查我的端点是否在查询预算内
我目前正在使用ASP.NET Core 3.1和EF Core 3.1,但我愿意升级以获得此功能
我尝试编写一个DbCommandInterceptor并将其添加到AddDbContext调用中,但似乎是通过AddEntityFrameworkStores添加的存储。。。与此隔离,因为从未调用过我的CommandCreating处理程序
这就是做这件事的方法。以下资料摘自:
services.AddDbContextoptions=>
options.UseSqlServerConfiguration.GetConnectionStringDefaultConnection;
services.AddDefaultIdentityoptions=>options.SignIn.RequiredConfirmedAccount=true
.附录框架库;
只需添加拦截器即可:
services.AddDbContextoptions=>
options.UseSqlServerConfiguration.GetConnectionStringDefaultConnection
.AddInterceptor新查询计数命令拦截器
;
请注意,您提到使用UseInMemoryDatabase,这可能仅在WebApplicationFactory类中执行。如果是这种情况,您也需要在那里添加拦截器:
public class WebApplicationFactory : WebApplicationFactory<Startup>
{
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.ConfigureServices(s => s.AddDbContext<ApplicationDbContext>(options =>
{
options.UseInMemoryDatabase("integration-tests");
options.AddInterceptors(new MyInterceptor());
}));
}
}
这很好,因为您可以只为测试添加拦截器,而不为生产代码运行拦截器
我尝试编写一个DbCommandInterceptor并将其添加到AddDbContext调用中,但似乎是通过AddEntityFrameworkStores添加的存储。。。与此隔离,因为从未调用过我的CommandCreating处理程序
这就是做这件事的方法。以下资料摘自:
services.AddDbContextoptions=>
options.UseSqlServerConfiguration.GetConnectionStringDefaultConnection;
services.AddDefaultIdentityoptions=>options.SignIn.RequiredConfirmedAccount=true
.附录框架库;
只需添加拦截器即可:
services.AddDbContextoptions=>
options.UseSqlServerConfiguration.GetConnectionStringDefaultConnection
.AddInterceptor新查询计数命令拦截器
;
请注意,您提到使用UseInMemoryDatabase,这可能仅在WebApplicationFactory类中执行。如果是这种情况,您也需要在那里添加拦截器:
public class WebApplicationFactory : WebApplicationFactory<Startup>
{
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.ConfigureServices(s => s.AddDbContext<ApplicationDbContext>(options =>
{
options.UseInMemoryDatabase("integration-tests");
options.AddInterceptors(new MyInterceptor());
}));
}
}
这很好,因为您可以只为测试添加拦截器,而不为生产代码运行拦截器。谢谢您的回答!我开始创建一个可复制的场景来回答你的最后一个问题,我本来应该这样做的:然后我自己找到了解决方案。-在我的WebApplicationFactory中,我覆盖AddDbContext以便能够使用MemoryDatabase。。。当然,你也需要在那里添加拦截器。你介意我在你的答案中编辑一些额外的细节,以帮助其他在这里着陆的人吗?当然,取得了成功!谢谢你的回答!我开始创建一个可复制的场景来回答你的最后一个问题,我本来应该这样做的:然后我自己找到了解决方案。-在我的WebApplicationFactory中,我覆盖AddDbContext以便能够使用MemoryDatabase。。。当然,你也需要在那里添加拦截器。你介意我在你的答案中编辑一些额外的细节,以帮助其他在这里着陆的人吗?当然,取得了成功!