我的以下查询有异步问题。我有单例上下文,我正在尝试执行以下查询:
var query = await (from parent in Context.ParentTable
join child in Context.ChildTable
on parent.ID equals child.ID
into allResult
from ResultValue in allResult.DefaultIfEmpty()
where ResultValue.TenantId == tenantId
select new Result
{
Code = parent.Code,
Type = parent.Type,
ID = ResultValue == null ? 0 : ResultValue.Id
}).ToListAsync();
我的单例上下文是这样的:
public class BaseRepository
{
private readonly IConfigurationContextFactory configurationContextFactory;
private IConfigurationContext context;
protected IConfigurationContext Context
{
get
{
return context ?? (context = configurationContextFactory.Context);
}
}
public BaseRepository(IConfigurationContextFactory configurationContextFactory)
{
this.configurationContextFactory = configurationContextFactory;
}
}
配置上下文工厂返回这样的上下文:
private ConfigurationContext Get()
{
logger.WriteEntrySync(LogLevel.Information,
null != context ? "Config Context: Using existing context." : "Config Context: Wiil create new context.");
return context ?? (context = new ConfigurationContext(connectionString));
}
在此我遇到以下错误的间歇性问题:
A second operation started on this context before a previous asynchronous operation completed. Use 'await' to ensure that any asynchronous operations have completed before calling another method on this context. Any instance members are not guaranteed to be thread safe.
最佳答案
I have singleton context
这是你的问题。 DbContext
不是线程安全的,旨在一次执行一个查询。由于您正在共享您的 DbContext
,您可能正在尝试同时调用另一个查询,这在 DbContext
术语中是不“合法的”。
您甚至可以在 remarks of ToListAsync
中看到它:
Multiple active operations on the same context instance are not supported. Use 'await' to ensure that any asynchronous operations have completed before calling another method on this context.
您应该做的不是通过在每次要查询数据库时创建一个新的上下文来重复使用具有全局单例的上下文。
编辑:
与其通过工厂方法获取单个 Context
,不如为每个查询分配一个新上下文:
using (var context = new ConfigurationContext(connectionString))
{
var query = await (from feature in context.Features
join featureFlag in context.FeatureFlags
on feature.FeatureId equals featureFlag.FeatureId
into allFeatures
from featureFlagValue in allFeatures.DefaultIfEmpty()
where featureFlagValue.TenantId == tenantId
select new BusinessEntities.FeatureFlag
{
Code = feature.Code,
Type = feature.Type,
FeatureFlagId = featureFlagValue == null ? 0 : featureFlagValue.FeatureFlagId
}).ToListAsync();
}
关于c# - Entity Framework 异步问题上下文或查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29763732/