前言
遇到一个需求需要在 C#下同时连接多种数据库,记录学习 C# 连接 PostgreSql 和 SqlServer 并实现 CodeFirst
理论
Enable-Migrations
由于在使用 ef6 进行数据库连接时都是通过Enable-Migrations
来设置多个数据库上下文的迁移文件路径的,进行了如下命令输入:
1
|
Enable-Migrations -ContextTypeName ef_demo.PgSqlCodeFirstDbContext -MigrationsDirectory Magrations\pgsql
|
其中\
不能打错否则发生错误
ContextTypeName:DbContext的位置,即 DbContext 的命名空间加上 DbContext 的名称
MigrationsDirectory:需要迁移到的目标文件夹
同样另一个数据上下文进行设置
1
|
Enable-Migrations -ContextTypeName ef_demo.SqlServerCodeFirstDbContext -MigrationsDirectory Magrations\sqlserver
|
Add-Migrations
通过运行Add-Migrations
命令
注意:通过Add-Migrations
命令会自动选择唯一的DbContext, 但是如果有多个DbContext, 必须指定需要对哪个DbContext进行修改
1
|
Add-Migration -ConfigurationTypeName ef_demo.Migrations.pgsql.Configuration InitPgsqlDb
|
这里通过-ConfigurationTypeName
指定Configuration 后面接着是Configuration的路径,然后接着是我们取得名字InitPgsqlDb
EF 会找到指定的 Configuration, 并添加 XXXX_InitPgsqlDb
Update-Database
最后通过Update-Database
进行更新,需要指定需要更新哪个Configuration
1
|
Update-Database -ConfigurationTypeName ef_demo.Migrations.pgsql.Configuration
|
命令详情
1
2
3
4
5
6
7
8
9
|
Enable-Migrations
-ContextTypeName EmployeeDBContext #context 类型
-MigrationsDirectory CreateMigrations #自定义数据迁移文件夹
-ProjectName 1-3EntityFrameWorkDemo #数据迁移类将被添加到哪个项目中
-StartUpProjectName 1-3EntityFrameWorkDemo #数据库连接字符串配置文件 所在的项目
-ContextProjectName 1-3EntityFrameWorkDemo #context 类所在项目
-ConnectionStringName EmployeeDBContext #数据库连接字符串 名称
-Force #多次运行,是否重写迁移文件
-Verbose #详细信息
|
1
2
3
4
5
6
7
8
|
Add-Migration
-Name MyFirstMigration #名称
-Force #强制执行,也就是说多次运行,会覆盖之前文件
-ProjectName 1-3EntityFrameWorkDemo #指定数据迁移类所在项目名称
-StartUpProjectName 1-3EntityFrameWorkDemo #数据库连接字符串所在项目名称
-ConfigurationTypeName EntityFrameWorkDemo.CreateMigrations.Configuration #指定数据迁移配置类
-ConnectionStringName EmployeeDBContext #指定数据库连接字符串
-Verbose #详细信息
|
1
2
3
4
5
6
7
|
Update-Database
-ProjectName 1-3EntityFrameWorkDemo 指定 migration configuration 所在项目
-StartUpProjectName 1-3EntityFrameWorkDemo #指定数据库连接字符串所在项目
-ConfigurationTypeName EntityFrameWorkDemo.CreateMigrations.Configuration #指定 Configuration 类
-ConnectionStringName EmployeeDBContext #数据库连接字符串
-Force #数据丢失被允许
-Verbose #详细信息
|
实战
开发环境
- Windows 10
- Visual Studio 2019
- C# 7.0
- .Net FrameWork 4.5.2
需求
- 需要连接 SqlServer
- 需要连接 PostgreSql
库
- EntityFramework
- EntityFramework6.Npgsql
示例代码
分别建立对应的 model,这边采用 CodeFirst 的方式,如果需要 DBFirst 请查询 官方教程 随后创建 Context 继承 DBContext
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
public class CodeFirstDbContext : DbContext
{
public CodeFirstDbContext()
: base(new SqlConnection(
new SqlConnectionStringBuilder()
{
DataSource = "localhost",
InitialCatalog = "test",
UserID = "sa",
Password = "123456",
}.ConnectionString), true)
{
}
private static SqlConnection SqlConnection()
{
var builder = new SqlConnectionStringBuilder();
builder.DataSource = "localhost";
builder.InitialCatalog = "test";
builder.UserID = "sa";
builder.Password = "123456";
return new SqlConnection(builder.ConnectionString);
}
public virtual DbSet<EntityModel.ControlDataEntity> ControlData { get; set; }
public virtual DbSet<EntityModel.V_MonitorOnlineEntity> V_MonitorOnline { get; set; }
}
|
1
2
3
4
5
6
7
8
9
10
11
|
public class CodeFirstPostgreSqlDbContext : DbContext
{
public CodeFirstPostgreSqlDbContext()
: base("Server=172.17.209.6;Database=test3; User Id=root;Password=123456;")
{
}
public virtual DbSet<EntityPostgreSQLModel.OEEAlarmInfosEntity> OEEAlarmInfos { get; set; }
public virtual DbSet<EntityPostgreSQLModel.ReportAlarmStatisticsEntity> ReportAlarmStatistics { get; set; }
}
|
注意: 上述连接多个数据库时,配置中默认使用 npgsql 连接,所以在连接 sqlserver 的时候需要手动通过 ConnectionStringBuilder 构造指定连接类型
使用如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
#if false
Task.Run(() =>
{
using (var db = new CodeFirstDbContext())
{
try
{
db.ControlData.Add(new Model.EntityModel.ControlDataEntity
{
CH = "123",
InstrumentID = 112,
AlarmValueLow = 456,
Unit = "I don't known",
Field1 = "789",
});
db.SaveChanges();
db.ControlData.ToList().ForEach(x => Console.WriteLine(x.CH + "\t" + x.AlarmValueLow));
}
catch (Exception ex)
{
System.Diagnostics.Debug.Print(ex.Message);
}
}
});
#endif
#if false
Task.Run(() =>
{
using (var db = new CodeFirstPostgreSqlDbContext())
{
try
{
db.OEEAlarmInfos.Add(new Model.EntityPostgreSQLModel.OEEAlarmInfosEntity { Code = "test3" });
db.SaveChanges();
db.OEEAlarmInfos.ToList().ForEach(x => Console.WriteLine(x.Code));
}
catch (Exception ex)
{
System.Diagnostics.Debug.Print(ex.Message);
}
}
});
#endif
|
参考
「# 通过 Migration 在 EF6 中用多个 DbContext」