zoukankan      html  css  js  c++  java
  • EF Core怪问题之通过依赖注入获取的上下文在执行异步写入数据库时抛出异常?

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

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


    出问题的代码如下:

     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(); //此处写入数据库时会抛出异常                
             }
        }

    经分析查找原因如下:

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

    解决办法:

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

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

    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);
  • 相关阅读:
    JSON跨域请求
    2013.9.26 心得体会
    MemCached用法
    使用SQL联合查询来构建临时vo对象的应用
    ubuntu 16.04 安装php 5 6等版本
    mac php版本切换
    windows 查看端口占用
    nginx 反向代理到目录
    linux挂在samba服务器到本地(用于备份文件到nas或者windows的文件服务器)
    ubuntu 加载新硬盘或分区
  • 原文地址:https://www.cnblogs.com/thinkingagain/p/12668407.html
Copyright © 2011-2022 走看看