EF Core怪问题之经过依赖注入获取的上下文在执行异步写入数据库时抛出异常?

此问题实质上是上下文生命周期的问题, 网上有篇文章对此问题分析的更加详细, 请参考:数据库

http://www.tnblog.net/aojiancc2/article/details/3283异步

 


 

出问题的代码以下:async

 public class DBBookChaptersService : IBookChaptersService
    {
        private readonly BooksContext _booksContext;
        public DBBookChaptersService(BooksContext booksContext)
        { _booksContext = booksContext;}
         public async Task Add(BookChapter bookChapter)
        {
           await _booksContext.Chapters.AddAsync(bookChapter);
           await _booksContext.SaveChangesAsync(); //此处写入数据库时会抛出异常                
         }
    }

经分析查找缘由以下:spa

经过依赖注入的上下文执行到SaveChangesAsync这个异步方法时,会直接Dispose掉, 致使回调失败..net

解决办法:code

1. 使用同步方法SaveChanges().
此方法最简单, 也能够新构造一个异步方法将其包起来实现异步调用.对象

2. 不用依赖注入的上下文, 而是临时生成上下文, 具体步骤以下:
此方法并不是彻底不使用依赖注入, 只是舍弃依赖注入上下文,而使用依赖注入的DbContextOptions<T>来构造临时上下文.blog

public class DBBookChaptersService : IBookChaptersService
    {
       private readonly BooksContext _booksContext;
        // 1. 采用依赖注入得到DbContextOptions
        private readonly DbContextOptions<BooksContext> _options;        
        public DBBookChaptersService(BooksContext booksContext, DbContextOptions<BooksContext> options)
        {
            _booksContext = booksContext;
            _options = options;
        }
         public async Task Add(BookChapter bookChapter)
        {
           // 2. 用optins生成临时上下文, 执行异步SaveChangesAsync()
            using (var context = new BooksContext(_options))
            {
                await context.Chapters.AddAsync(bookChapter);
                await context.SaveChangesAsync();
            }

 在网友的启发下, 发现Dispose的缘由是上下文的生命周期问题. 可在注册服务时将其设为单例模式便可解决:生命周期

services.AddDbContext<BooksContext>(options => options.UseSqlServer(
                Configuration.GetConnectionString("BooksConnection")), ServiceLifetime.Singleton, ServiceLifetime.Singleton);
相关文章
相关标签/搜索