.NetCore通过EFCore操作数据库
安装nuget包
efcore官方支持的数据库包括SQLServer、MySql、PostgreSQL、Sqlite
我们这里使用SQLServer数据库
添加数据库上下文类和数据模型
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public class YFDbContext : DbContext 2 { 3 /// <summary> 4 /// 构造函数 5 /// </summary> 6 public YFDbContext() 7 { 8 9 } 10 protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) 11 { 12 //private string ConnstrSqlServer = "server=服务器名称;uid=登录名称;pwd=登录密码;database=数据库名称"; 13 optionsBuilder.UseSqlServer(@"server=数据库地址;uid=sa;pwd=数据库密码;database=CoreDB"); 14 base.OnConfiguring(optionsBuilder); 15 } 16 /// <summary> 17 /// 通过依赖注入方式启动的构造函数 18 /// </summary> 19 /// <param name="options"></param> 20 //public YFDbContext(DbContextOptions<YFDbContext> options) : base(options) 21 //{ 22 23 //} 24 public DbSet<UserInfo> UserInfo { get; set; } 25 public DbSet<RoleInfo> RoleInfo { get; set; } 26 27 /// <summary> 28 /// 重写Dispose方法,便于查看数据库上下文什么时候释放。 29 /// </summary> 30 public override void Dispose() 31 { 32 base.Dispose(); 33 Console.WriteLine("\n***Dispose****\n\n"); 34 } 35 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public class UserInfo 2 { 3 public string Id { get; set; } 4 public string UserName { get; set; } 5 public string UserSex { get; set; } 6 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public class RoleInfo 2 { 3 public string Id { get; set; } 4 public string RoleName { get; set; } 5 public string RoleDescription { get; set; } 6 }
添加测试控制器
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public class EFTestController : Controller 2 { 3 /// <summary> 4 /// 测试EFCore插入数据 5 /// 每次需要实例化数据库上下文 6 /// </summary> 7 /// <returns></returns> 8 public JsonResult TestInsert() 9 { 10 List<UserInfo> uList; 11 using (var db=new YFDbContext()) 12 { 13 //1.新增 14 UserInfo userInfo = new UserInfo() 15 { 16 Id = Guid.NewGuid().ToString("N"), 17 UserName = "张三", 18 UserSex = "男" 19 }; 20 //同步方法 21 db.Add(userInfo); 22 int count = db.SaveChanges(); 23 //异步方法 24 //await _db.Set<UserInfo>().AddAsync(userInfo); 25 //int count = await _db.SaveChangesAsync(); 26 Console.WriteLine($"成功插入{count}条数据"); 27 //2.查询 28 uList = db.Set<UserInfo>().ToList(); 29 foreach (var item in uList) 30 { 31 Console.WriteLine($"id为:{item.Id},名字为:{item.UserName},性别为:{item.UserSex}"); 32 } 33 } 34 return Json(uList); 35 } 36 }
执行结果:
我这里使用了谷歌浏览器JsonView插件。
升级:通过依赖注入方式获取数据库上下文
在appsettings.json中配置数据库连接字符串
在Startup.cs文件ConfigureServices方法中添加服务
改造控制器,通过依赖注入方式获取数据库上下文
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public class EFTestIOCController : Controller 2 { 3 private readonly YFDbContext _db; 4 private readonly DbContextOptions<YFDbContext> _options; 5 public EFTestIOCController(YFDbContext db, DbContextOptions<YFDbContext> options) 6 { 7 _db = db; 8 _options = options; 9 } 10 public IActionResult Index() 11 { 12 return View(); 13 } 14 /// <summary> 15 /// 测试EFCore插入数据 16 /// 通过依赖注入方式获取数据库上下文 17 /// </summary> 18 /// <returns></returns> 19 public JsonResult TestInsert() 20 { 21 List<UserInfo> uList; 22 using (var db = new YFDbContext()) 23 { 24 //1.新增 25 UserInfo userInfo = new UserInfo() 26 { 27 Id = Guid.NewGuid().ToString("N"), 28 UserName = "张三", 29 UserSex = "男" 30 }; 31 //同步方法 32 db.Add(userInfo); 33 int count = db.SaveChanges(); 34 35 Console.WriteLine($"成功插入{count}条数据"); 36 //2.查询 37 uList = db.Set<UserInfo>().ToList(); 38 foreach (var item in uList) 39 { 40 Console.WriteLine($"id为:{item.Id},名字为:{item.UserName},性别为:{item.UserSex}"); 41 } 42 } 43 return Json(uList); 44 } 45 }
执行结果:
问题
再次调用http://localhost:5000/EFTestIOC/TestInsert方法或者使用异步方法插入数据时会报一下错误,该问题的原因是依赖注入方式的数据库上下文生命周期
解决办法:用 DbContextOptions 手工 new DbContext
System.ObjectDisposedException:“Cannot access a disposed object. A common cause of this error is disposing a context that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur if you are calling Dispose() on the context, or wrapping the context in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances. ”
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public async void TestMultInsert() 2 { 3 System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch(); 4 watch.Start(); //开始监视代码运行时间 5 using (var context = new YFDbContext(_options)) 6 { 7 8 for (int i = 0; i < 10; i++) 9 { 10 //1.新增 11 UserInfo userInfo = new UserInfo() 12 { 13 Id = Guid.NewGuid().ToString("N"), 14 UserName = "ypf3", 15 UserSex = "男" 16 }; 17 await context.Set<UserInfo>().AddAsync(userInfo); 18 int count = await context.SaveChangesAsync(); 19 Console.WriteLine($"成功插入{count}条数据"); 20 } 21 } 22 watch.Stop(); //停止监视 23 TimeSpan timespan = watch.Elapsed; //获取当前实例测量得出的总时间 24 Console.WriteLine($"代码执行时间:{timespan.TotalMilliseconds}"); 25 }