.net core EF SaveChangesAsync时,会Dispose导致异常

 1 public class BaseRepositories<T>  where T : class
 2     {
 3         private readonly RepositoryDbContext _context;
 4 
 5         public BaseRepositories(RepositoryDbContext context)
 6         {
 7             _context = context;
 8         }
 9 
10         /// <summary>
11         /// 添加
12         /// </summary>
13         /// <param name="entity"></param>
14         /// <returns></returns>
15         public async Task<bool> Add(T entity)
16         {
17 
18             await _context.Set<T>().AddAsync(entity);
19             return await _context.SaveChangesAsync() > 0;//执行到这行会报错
20             /* 错误信息:
21              * 无法访问已释放的对象。导致此错误的一个常见原因是处理从依赖项注入解析的上下文,
22              * 然后在应用程序的其他地方尝试使用相同的上下文实例。如果对上下文调用Dispose(),
23              * 或将上下文包装到using语句中,则可能会发生这种情况。如果使用的是依赖项注入,
24              * 则应让依赖项注入容器处理上下文实例。\r\n对象名称:“RepositoryDbContext”
25              */
26         }
27     }

1.通过分析原因是:

数据库上下文对象被销毁了,是在什么时候销毁的呢?通过跟踪程序 是在 _context.AddAsync(entity);

调用AddAsync后, 执行了DbContext.Dispose(),可以通过重写 DbContext.Dispose() 方法来输出执行顺序来证明。这里就不做演示了。

2.问题解决方案:三个方式

   2.1通过使用同步方法_context.Add()和_context.SaveChanges()

  这个方法比较简单,如果要实现异步,自定义一个异步方法将其包含就可以了。

   2.2不用依赖注入的上下文, 而是临时生成上下文, 具体步骤如下:

  此方法并非完全不使用依赖注入, 只是舍弃依赖注入上下文,而使用依赖注入的DbContextOptions<T>来构造临时上下文

 1 public class BaseRepositories<T>  where T : class
 2     {
 3         private readonly RepositoryDbContext _context;
 4 
 5         // 1. 采用依赖注入获得DbContextOptions
 6         private readonly DbContextOptions<RepositoryDbContext> _options;
 7         public BaseRepositories(RepositoryDbContext context, DbContextOptions<RepositoryDbContext> options)
 8         {
 9             _options = options;
10             _context = context;
11         }
12 
13         /// <summary>
14         /// 添加
15         /// </summary>
16         /// <param name="entity"></param>
17         /// <returns></returns>
18         public async Task<bool> Add(T entity)
19         {
20             // 2. 用optins生成临时上下文, 执行异步SaveChangesAsync()
21             using (var context = new RepositoryDbContext(_options)) 
22             {
23                 await context.Set<T>().AddAsync(entity);
24                 return await context.SaveChangesAsync() > 0;
25             }
26            
27         }
28     }

3.通过注册服务时使用单例模式:

在网上搜到相关的Dispose原因,是上下文的生命周期的问题。

services.AddDbContext<RepositoryDbContext>(options => options.UseSqlServer(
                Configuration.GetConnectionString("AppOptions")), ServiceLifetime.Singleton, ServiceLifetime.Singleton);

 

.net core EF SaveChangesAsync时,会Dispose导致异常

上一篇:Visual Studio 链接 Sql Sever 提示启动进程时出错 ->解决方案


下一篇:php 执行GuzzleHttp请求时发生cURL error 60: SSL certificate problem错误的解决方法