EF 核心错误与交易但不使用交易
EF core error with transaction but not using trasactions
最近我们的一位测试员报告了我们应用程序的错误。
此错误似乎与 EF 核心事务有关,但我们没有在代码中使用事务。但是我们在这个应用上根本没有使用交易。
当多个用户连接到我们的应用程序时,这个问题似乎是随机发生的。
错误是:
Error : System.invalidOperationException
BeginExecuteReader require the command to have a transaction when the connection assigned to the command is in a pending local transaction.
The transaction property of the command has not been initialized.
从堆栈跟踪来看,当我们在名为“SurveyOperations”的 class 中执行以下操作时,就会发生此错误:
Survey surveyToSave = await _context.Surveys.FindAsync(id);
详情:
_context 在 SurveyOperations 构造函数中使用 asp.net 核心依赖注入进行初始化。
在 startup.cs 中,SurveyOperations 的范围为“瞬态”,数据库连接也是如此。
我们 100% 的 EF 核心调用都是异步的。
我们在使用 OwningComponentBase 注入 SurveyOperations 的 Blazor 组件上遇到此错误:
@using Microsoft.Extensions.DependencyInjection
@inherits OwningComponentBase
@code{
private SurveyOperations _surveyOperations;
private Survey survey;
protected override async Task OnInitializedAsync()
{
_surveyOperations = ScopedServices.GetRequiredService<SurveyOperations>();
survey = await _surveyOperations.GetSurveyAsync(id);
}
private async Task HandleValidSubmit()
{
// Get sone data from the form on the component
await _surveyOperations.SaveSurvey(survey);
}
}
```
We suspect that EF core is reusing connections but we didn't know how to avoid that.
在我看来,您的设计是错误的,使用 OwningComponentBase
并不能确保您免受在 Blazor 中使用 DbContext 引起的问题。您可以使用以下方法之一解决此问题:
@inherits OwningComponentBase<AppDbContext>
AppDbContext
是您的 DbContext
或者更好,更适合您的设计,实施 IDbContextFactory...在这种情况下,您可以像这样配置 dbcontext:
builder.Services.AddDbContextFactory<ContactContext>(opt =>
opt.UseSqlite($"Data Source={nameof(ContactContext.ContactsDb)}.db"))
在这里查看完整的解释:full explanation
在您的 SurveyOperations
服务中,您可以这样做:
public SurveyOperations(IDbContextFactory<ContactContext> factory)
{
DbFactory = factory;
}
在你的各种方法中你可以做这样的事情:
using var _context = DbFactory.CreateDbContext();
Survey surveyToSave = await _context.Surveys.FindAsync(id);
请注意,第二个选项使 OwningComponentBase
的使用变得多余。
最近我们的一位测试员报告了我们应用程序的错误。 此错误似乎与 EF 核心事务有关,但我们没有在代码中使用事务。但是我们在这个应用上根本没有使用交易。
当多个用户连接到我们的应用程序时,这个问题似乎是随机发生的。
错误是:
Error : System.invalidOperationException
BeginExecuteReader require the command to have a transaction when the connection assigned to the command is in a pending local transaction.
The transaction property of the command has not been initialized.
从堆栈跟踪来看,当我们在名为“SurveyOperations”的 class 中执行以下操作时,就会发生此错误:
Survey surveyToSave = await _context.Surveys.FindAsync(id);
详情:
_context 在 SurveyOperations 构造函数中使用 asp.net 核心依赖注入进行初始化。
在 startup.cs 中,SurveyOperations 的范围为“瞬态”,数据库连接也是如此。 我们 100% 的 EF 核心调用都是异步的。
我们在使用 OwningComponentBase 注入 SurveyOperations 的 Blazor 组件上遇到此错误:
@using Microsoft.Extensions.DependencyInjection
@inherits OwningComponentBase
@code{
private SurveyOperations _surveyOperations;
private Survey survey;
protected override async Task OnInitializedAsync()
{
_surveyOperations = ScopedServices.GetRequiredService<SurveyOperations>();
survey = await _surveyOperations.GetSurveyAsync(id);
}
private async Task HandleValidSubmit()
{
// Get sone data from the form on the component
await _surveyOperations.SaveSurvey(survey);
}
}
```
We suspect that EF core is reusing connections but we didn't know how to avoid that.
在我看来,您的设计是错误的,使用 OwningComponentBase
并不能确保您免受在 Blazor 中使用 DbContext 引起的问题。您可以使用以下方法之一解决此问题:
@inherits OwningComponentBase<AppDbContext>
AppDbContext
是您的 DbContext
或者更好,更适合您的设计,实施 IDbContextFactory...在这种情况下,您可以像这样配置 dbcontext:
builder.Services.AddDbContextFactory<ContactContext>(opt =>
opt.UseSqlite($"Data Source={nameof(ContactContext.ContactsDb)}.db"))
在这里查看完整的解释:full explanation
在您的 SurveyOperations
服务中,您可以这样做:
public SurveyOperations(IDbContextFactory<ContactContext> factory)
{
DbFactory = factory;
}
在你的各种方法中你可以做这样的事情:
using var _context = DbFactory.CreateDbContext();
Survey surveyToSave = await _context.Surveys.FindAsync(id);
请注意,第二个选项使 OwningComponentBase
的使用变得多余。