c#-将DataContext放置在ASP.NET Core调度程序中 [英] c# - DataContext disposed in ASP.NET Core scheduler

查看:89
本文介绍了c#-将DataContext放置在ASP.NET Core调度程序中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经在我的ASP.NET应用程序中包含了Coravel调度程序。

I have included Coravel scheduler in my ASP.NET application.

一切似乎都运行良好,但是当调度程序开始运行时,它在DataContext上返回System.ObjectDisposedException。 。
我在我的存储库类中使用了依赖注入,是否仅在接收到来自浏览器的请求时才创建上下文?
如何解决此问题,以便调度程序运行该方法时上下文可用?

Everything seems to work well, but when the scheduler starts running it returns System.ObjectDisposedException on the DataContext. I use Dependency Injection in my repository classes, does the context only get created when it receives a request from the browser? How can I fix this so the context is available when my scheduler runs the method?

下面是我的存储库代码

using System.Collections.Generic;
using System.Threading.Tasks;
using Project.Models;
using Microsoft.EntityFrameworkCore;
using System.Linq;


namespace Project.Data.CustomerRepo
{
    public class CustomerRepository : ICustomerRepository
    {
        private readonly DataContext _context;
        public CustomerRepository(DataContext context)
        {
            this._context = context;

        }
        public async Task<Customer> Create(Customer customer)
        {
            await _context.Customers.AddAsync(customer);
            return customer;
        }

        public async Task<IEnumerable<Customer>> Create(IEnumerable<Customer> customers)
        {
            await _context.Customers.AddRangeAsync(customers);
            await _context.SaveChangesAsync();
            return customers;
        }

        public async Task Delete(Customer customer)
        {
            _context.Customers.Remove(customer);
            await _context.SaveChangesAsync();
        }

        public async Task<Customer> Read(int id)
        {
            var customer = await _context.Customers.FirstOrDefaultAsync(customerItem => customerItem.Id == id);
            return customer;
        }
        public async Task<Customer> ReadFromFacebookId(string id)
        {
            var customer = await _context.Customers.Where(customerItem => customerItem.FacebookId == id).FirstOrDefaultAsync();
            return customer;
        }

        public async Task<IEnumerable<Customer>> Read()
        {
            var customers = await _context.Customers.ToListAsync();
            return customers;
        }

        public async Task<Customer> Update(Customer customer)
        {
            _context.Update(customer);
            await _context.SaveChangesAsync();
            return customer;
        }
    }
}


推荐答案

services.AddDbContext<>() DataContext 注册为具有 ServiceLifetime.Scoped ,这意味着您的 DataContext 是根据每个Web请求创建的。

services.AddDbContext<>()registers the DataContext as a service with ServiceLifetime.Scoped which means that your DataContext is created per web request. It is disposed when request is completed.

您可以将 IServiceScopeFactory 注入到您的控制器/存储库中,然后,将其丢弃。使用 CreateScope()创建一个新范围,并从该范围请求 DataContext 服务

You could inject IServiceScopeFactory which is singleton into your controller/repository, then create a new scope using CreateScope() and request the DataContext service from that scope

public class CustomerRepository : ICustomerRepository
{
    IServiceScopeFactory _serviceScopeFactory
    public CustomerRepository(IServiceScopeFactory serviceScopeFactory)
    {
        _serviceScopeFactory = serviceScopeFactory;
    }
    public async Task<Customer> Create(Customer customer)
    {
        using (var scope = _serviceScopeFactory.CreateScope())
        {
            var context = scope.ServiceProvider.GetRequiredService<DataContext>();              
            await context.Customers.AddAsync(customer);
            return customer;
        }

        return customer;

    }
}

请参考从后台任务访问DbContext服务

这篇关于c#-将DataContext放置在ASP.NET Core调度程序中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆