菜鸡之NetCore 使用EF操作数据库 Oracle & Sqlserver (一)
摘要:
该篇文章主要记录netcore efcore 如何操作oracle和sqlserver 数据库,采用codefirst方式创建数据库以及表。
一, 项目建立
项目采用ddd领域驱动设计模式【学习中】,目录介绍
1. application :服务层,【暂时不建立服务】
2. domain :业务领域层,主要就是一些仓储定义已经业务逻辑,当前项目定义数据库实体以及仓储定义
3. infrastructure :基础设施层,提供公共功能组件,当前项目实现oracle&sqlserver数据库的操作以及仓储的实现
4.presentation :webapi放在这感觉不合适,但是放在application中也好像不合适
二. 数据库实体(表)设计
1. 在demo.core项目中新建文件夹entities,该文件夹主要存放数据库实体相关信息,这里仅仅包含一个实体student
2. 在entites文件夹下新增student.cs类
1 namespace demo.core.entities 2 { 3 [table("student")] //指定数据库对应表名 4 public class student 5 { 6 /// <summary> 7 /// 学生学号 8 /// </summary> 9 [key] //主键 10 [column("userid")] //指定数据库对应表栏位名称 11 public string userid { get; set; } 12 13 /// <summary> 14 /// 学生姓名 15 /// </summary> 16 [maxlength(10)] 17 [column("name")] 18 public string name { get; set; } 19 } 20 }
填坑记录:指定数据库表名和栏位名为大小,否则我们使用pl/sql进行查询的时候就要加入引号,因为pl/sql以及一些工具是不分大小写,使用起来很不方便。若强行使用驼峰命名,在数据库工具查询方法如下:
1 select "userid","name" from "student";
三. 创建dbcontext
1.项目demo.efcore中nuget数据库驱动包
oracle => oracle.entityframeworkcore 【目前为止是预发行版本2.19.0-beta4】
sqlserver => microsoft.entityframeworkcore 【目前为止稳定版本2.2.4】
可以同时都安装如果有需要。在搜索oracle驱动的时候,要选中旁边的【包含预发行版本】
2.添加对项目demo.core的引用
3. 新建demodbcontext.cs
1 namespace demo.efcore 2 { 3 public class demodbcontext : dbcontext 4 { 5 public demodbcontext(dbcontextoptions<demodbcontext> options) 6 :base(options) 7 { 8 9 } 10 11 //该处定义你要映射到数据库中的表 12 //格式固定 13 public dbset<student> student { get; set; } 14 15 protected override void onmodelcreating(modelbuilder modelbuilder) 16 { 17 //判断当前数据库是oracle 需要手动添加schema(dba提供的数据库账号名称) 18 if(this.database.isoracle()) 19 { 20 modelbuilder.hasdefaultschema("netcore"); 21 } 22 base.onmodelcreating(modelbuilder); 23 } 24 25 } 26 }
填坑记录:如果使用oracle必须手动添加schema
四. 配置demo.webapi 项目
1.添加对 demo.efcore项目引用
2.修改配置文件 appsetting.json ,添加连接字符串信息dbconn,如下代码
1 { 2 "logging": { 3 "loglevel": { 4 "default": "warning" 5 } 6 }, 7 "allowedhosts": "*", 8 "dbconn": { 9 "oraconn": "user id=netcore;password=netcore2019;data source=10.244.247.124:1521/orcl;", 10 "sqlconn": "server=10.244.4.236\\nemo;database=netcore;user id=sa;password=sa2016;" 11 } 12 }
3.修改 startup.cs 文件中 , 修改configureservices方法注册oralce&sqlserver连接
根据需要使用oracle或者sqlserver,当前模式下只能选择一个。
填坑记录:在使用oracle的时候一定要先请dba将账号建制好
五.数据库迁移
1. 设定demo.webapi作为系统启动项
2.打开程序包管理控制台 => 默認项目选择demo.efcore
3.控制台中输入:add-migration init
此时会在demo.efcore中生成一个文件夹 migrations,该文件记录了数据迁移记录
4.控制台输入:update-database
5.数据库查询表已经生成
如果修改了实体对象(比如新增表或者修改表栏位)后,依次执行步骤3,4即可将修改结果保存到对应的数据库。
扩展:
1. dbcontext.database.ensuredeleted(); dbcontext.database.ensurecreated();用这两个方法,可以简单粗暴的将数据库删除在重建,就不用手动输入命令进行迁移,这样做很显然会导致数据库中已有的数据丢失。
2. 我们也可以使用dbcontext.database.migrate()代替输入“update-database”命令而在程式中自动迁移,但是没有找到替代“add-migration”的命令。
六.初始化数据库表值
通常我们在上线项目后,数据库中都会有些初始值,在codefirst模式下,我们通过代码在数据库生成后将值注入。
1.在demo.efcore 新建demoinitial.cs
1 public class demoinitial 2 { 3 public static void initial(dbcontext dbcontext) 4 { 5 //简单粗暴创建数据库 6 //删除数据库后从新创建数据库 7 //如果删除报错,就手动去数据库删除 8 //dbcontext.database.ensuredeleted(); 9 //dbcontext.database.ensurecreated(); 10 11 //程式自动检测有没有新的迁移没有反应到数据,有则更新数据库 12 if(dbcontext.database.getpendingmigrations().tolist().count()>0) 13 { 14 dbcontext.database.migrate(); 15 } 16 17 //根据某一个表是否有数据来判断是否需要注入初始数据 18 if(!dbcontext.set<student>().any()) 19 { 20 var student = new student() 21 { 22 userid = "c3700408", 23 name = "nemo" 24 }; 25 dbcontext.set<student>().add(student); 26 dbcontext.savechanges(); 27 } 28 29 30 } 31 }
2.修改demo.webapi program,因为我们要在项目启动的时候去做这些事
1 public static void main(string[] args) 2 { 3 var host = createwebhostbuilder(args).build(); 4 using (var scope = host.services.createscope()) 5 { 6 var services = scope.serviceprovider; 7 try 8 { 9 demodbinitial.initial(services.getservice<demodbcontext>()); 10 } 11 catch (exception ex) 12 { 13 //do something 14 } 15 } 16 host.run(); 17 }
3.运行代码,检测数据库
总结:
上一篇: 无私奉献的精神