c# - 在异步方法完成之前处理 EF Core DbContext

标签 c# entity-framework dbcontext ef-core-2.0

我遇到了我的 DbContext 被提前处理的问题。只有在调用任何 *Async 方法时才会明显,例如 ToListAsync() - 如果我调用任何同步方法,一切都很好。

我不知道我做错了什么。

有什么建议吗?

这是我认为需要的所有代码。

DbContext 及其接口(interface)

public interface IMyDbContext
{
    DbSet<MyModel> MyModels { get; set; }
}

public class MyDbContext : DbContext, IMyDbContext
{
    public DbSet<MyModel> MyModels { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);

    }

    public MyDbContext(DbContextOptions<MyDbContext> options) : base(options) { }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.ApplyConfiguration(new MyModelConfig());           
    }
}

使用此 DbContext 的存储库

public class MyModelRepository : IMyModelRepository
{
    private readonly IMyDbContext _dbContext;
    private string _baseSql = "Some SQL here ";

    public MyModelRepository(IMyDbContext dbContext)
    {
        _dbContext = dbContext;
    }

    public async Task<IList<MyModel>> GetAllAsync(Paging paging, Permission permission)
    {

        if (permission == null)
            throw new ArgumentNullException("permission");

        string sql = ApplyFilter(_baseSql, permission);

        try
        {
            // THIS FAILS
            return await _dbContext.MyModels.FromSql(sql).Skip(paging.Skip).Take(paging.Take).ToListAsync();

            // THIS FAILS
            return await _dbContext.MyModels.FromSql(sql).ToListAsync();

            // THIS WORKS
            return await _dbContext.MyModels.FromSql(sql).ToList(); 

        }
        catch (Exception e)
        {

            throw new InvalidOperationException("Could not retrieve data", e);
        }
    }
}

我正在通过如下所示的服务调用存储库:

public class GetAllMyModelQuery : IGetAllMyModelQuery
{
    private readonly IMyModelRepository _myModelRepository;
    private readonly IPermissionService _permissionService;
    private readonly ILogger _logger;

    public GetAllAbsenceQuery(IMyModelRepository myModelRepository, IPermissionService permissionService, ILogger<GetAllMyModelQuery> logger)
    {
        _myModelRepository = myModelRepository;
        _permissionService = permissionService;
        _logger = logger;
    }

    public async Task<IList<Emp_AbsenceEtrac>> Execute(Paging paging)
    {
        if (_permissionService.Permission == null)
        {
            _logger.LogInformation("No permission to the requested resource");
            return null;
        }

        // if external?
        // call external repo

        //TODO//

        // else
        return await _myModelRepository.GetAllAsync(paging, _permissionService.Permission);
    }
}

这又被 Controller 调用

public class MyModelController : Controller
{
    private readonly IQueryStore _queryStore;

    public MyModelController(IQueryStore queryStore)
    {
        _queryStore = queryStore;
    }

    [HttpGet]
    [ProducesResponseType(typeof(int), (int)HttpStatusCode.OK)]
    [ProducesResponseType(typeof(BadRequestObjectResult), (int)HttpStatusCode.BadRequest)]
    public async Task<IActionResult> Index([FromQuery] int offset = 0, [FromQuery] int limit = 25)
    {
        Paging paging = new Paging(offset, limit);
        return Ok(_queryStore.GetAllMyModelQuery.Execute(paging));
    }
}

最后,在启动时将它们连接在一起:

services.AddScoped<IMyDbContext, MyDbContext>();
services.AddScoped<IMyModelRepository, MyModelRepository>();    
// Everything else above is also added as scope..

 services.AddDbContext<MyDbContext>(opts =>
{
    opts.UseSqlServer(Configuration.GetConnectionString("MyDb"),
        sqlServerOptions =>
        {
            sqlServerOptions.CommandTimeout(600);
            // required to allow skip/take on sql server 2008
            sqlServerOptions.UseRowNumberForPaging(true);
        });
}); 

是否有任何跳出会导致我的异步调用导致 Db 连接关闭?

错误是:

enter image description here

最佳答案

您应该在 Index Controller 操作中等待 GetAllMyModelQuery.Execute 方法:

[HttpGet]
[ProducesResponseType(typeof(int), (int)HttpStatusCode.OK)]
[ProducesResponseType(typeof(BadRequestObjectResult), (int)HttpStatusCode.BadRequest)]
public async Task<IActionResult> Index([FromQuery] int offset = 0, [FromQuery] int limit = 25)
{
    Paging paging = new Paging(offset, limit);
    return Ok(await _queryStore.GetAllMyModelQuery.Execute(paging).ConfigureAwait(false));
}

关于c# - 在异步方法完成之前处理 EF Core DbContext,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51950058/

相关文章:

c# - 为多级表达式生成 Expression<Func<TEntity, bool>>

asp.net - EF、UoW 和存储库 - 何时在 WebForms 中处理 UnitOfWork?

c# - 使用dbContext的正确方法

.net - 如果我调用 DbContext.Dispose 而不调用 DbContext.SaveChanges 会怎样?

visual-studio-2010 - 为什么当我想使用 EF Power 工具查看我的模型时出现错误?

c# - 通过 CSV 文件将 MySQL 转换为 Azure SQL

c# - Dapper 参数化查询导致问题的字符串值?

c# - GridView 不显示所有行

c# - 从 C#/WPF 调用 C++ 程序

c# - Linq to sql 选择一个新类