c# - Entity Framework 异步问题上下文或查询?

标签 c# entity-framework asynchronous async-await

我的以下查询有异步问题。我有单例上下文,我正在尝试执行以下查询:

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/

相关文章:

c# - 单个表单中的单独代码 [C#]

c# - 声明对象类型的接口(interface)

asp.net - 如何扩展 aspnet 成员身份验证表?

c# - 保持IEnumerable和ObservableCollection同步

c# - Entity Framework 代码优先数据库未更新

java - ListenableFuture 链可以处理内部 ExecutionException 吗?

c# - 属性和变量之间的区别

javascript - 异步延迟 JS 直到满足条件

javascript - RxJs 处理异常而不终止

c# - Entity Framework - 按同一列中的多个条件选择 - 多对多