将 ToList 更改为 ToListAsync 确实可以解决"second operation started on this context"



在长时间运行我的代码后,最后我得到如下错误:

无效操作异常:在上一个操作完成之前,在此上下文上启动了第二个操作。这通常是由使用同一 DbContext 实例的不同线程引起的,但是不能保证实例成员是线程安全的。这也可能是由在客户端上评估的嵌套查询引起的,如果是这种情况,请重写查询以避免嵌套调用。

每次在具有以下功能的行上都会发生错误:

context FromSql with ToList

如果我将其更改为:

await context FromSql ToListAsync

并将方法更改为:

async Task<>

这真的是正确的解决方案吗?

-------------更新--------------------- 我有一个控制器,其他控制器从中继承

public abstract class PortalController  : Controller
{
protected readonly UserManager<SuUserModel> _userManager;
protected readonly ILanguageRepository _language;
protected readonly SuDbContext _context;
public  PortalController(UserManager<SuUserModel> userManager
, ILanguageRepository language
, SuDbContext context
)
{
_userManager = userManager;
_language = language;
_context = context;
}

在这里,我定义上下文。

在继承此内容的控制器中,它看起来像:

public class ContentTypeController : PortalController
{
private readonly IContentTypeLanguageRepository _contentTypeLanguage;
private readonly IContentTypeRepository _contentType;
public ContentTypeController(UserManager<SuUserModel> userManager
, IContentTypeLanguageRepository ContentTypeLanguage
, IContentTypeRepository contentType
, ILanguageRepository language
, SuDbContext context
) : base(userManager, language, context)
{
_contentTypeLanguage = ContentTypeLanguage;
_contentType = contentType;
}

以前,我没有使用这个基本控制器。

此外,我使用 ServiceLifetime.Transient 更改了 Startup.cs 连接字符串,但没有帮助:

services.AddDbContext<SuDbContext>(options => {options.UseSqlServer(Configuration.GetConnectionString("SuConnectionString"));}, ServiceLifetime.Transient);

--------------------------更新------------------------------

试图弄清楚更多关于这一点的信息。 在我的控制器中,我调用以下方法:

public async Task<IActionResult> Index()
{
var CurrentUser = await _userManager.GetUserAsync(User);
base.Initializing();
var parameter = new SqlParameter("@LanguageId", CurrentUser.DefaultLanguageId);
var OrganizationType = _context.ZdbObjectIndexGet.FromSql("OrganizationTypeIndexGet @LanguageId", parameter).ToList();
return View(OrganizationType);

从基本控制器调用:

public async void Initializing()
{
var CurrentUser = await _userManager.GetUserAsync(User);
var DefaultLanguageID = CurrentUser.DefaultLanguageId;
var UICustomizationArray = new UICustomization(_context);
ViewBag.Terms = UICustomizationArray.UIArray(this.ControllerContext.RouteData.Values["controller"].ToString(), this.ControllerContext.RouteData.Values["action"].ToString(), DefaultLanguageID);
Menus a = new Menus(_context);
ViewBag.menuItems = a.TopMenu(DefaultLanguageID);
return;
}

这调用了类 UICustomization 中的 UIArray 方法:

public class UICustomization
{
private readonly SuDbContext _context;
public UICustomization(SuDbContext context)
{
_context = context;
}
public string[] UIArray(string Controller, string Action, int languageId)
{
//UI Customization
SqlParameter[] parameters =
{
new SqlParameter("@Controller", Controller)
, new SqlParameter("@Action", Action)
, new SqlParameter("@LanguageId", languageId)
};
var CustomizationFromDb = _context.ZdbLayoutTermList.FromSql("UITermLanguageSelect @Controller, @Action, @LanguageID", parameters).ToList();
int NoOfTerms = CustomizationFromDb.Count();
String[] CustomTerms = new String[NoOfTerms];
int i = 0;
foreach (var x in CustomizationFromDb)
{
CustomTerms[i] = x.Name;
i++;
}
return CustomTerms;
//UI Customization
}

当我运行它时,使用第一种方法时,我收到错误。因此,我认为它应该是此控制器/基本控制器和正在调用的类的一部分:

看起来如果我调用一个包含 await 语句的方法,我在调用实际方法时也必须使用 await。

相关内容

最新更新