初始化及配置
EntityContext
在使用之前,要确保能够正确地连接到目标数据库,如果你未指定数据库连接串,那么 EntityContext
就无法正常工作。EntityContext
的配置有以下几种。
1、默认配置
在提供数据库实例配置的情况下,你可以什么都不用考虑,只需 new EntityContext() 来使用。如数据库实例配置如下:
- .Net Framework 下的 app.config 或 web.config 文件
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="fireasy">
<section name="dataInstances" type="Fireasy.Data.Configuration.InstanceConfigurationSectionHandler, Fireasy.Data" />
</sectionGroup>
</configSections>
<fireasy>
<dataInstances default="sqlite">
<instance name="mysql" providerType="MySql" connectionString="Data Source=localhost;database=Northwind;User Id=root;password=faib;pooling=true;charset=utf8"></instance>
<instance name="mssql" providerType="MsSql" connectionString="data source=(local);user id=sa;password=123;initial catalog=fireasy-db"></instance>
<instance name="sqlite" providerType="SQLite" connectionString="Data source=|datadirectory|documents/db/northwind.db3;Pooling=True"></instance>
</dataInstances>
</fireasy>
</configuration>
- .Net Core 下的 appsettings.json 文件
{
"fireasy": {
"dataInstances": {
"default": "sqlite",
"settings": {
"mysql": {
"providerType": "MySql",
"connectionString": "Data Source=localhost;database=northwind;User Id=root;password=faib;pooling=true;charset=utf8"
},
"mssql": {
"providerType": "MsSql",
"connectionString": "data source=(local);user id=sa;password=123;initial catalog=test;"
},
"sqlite": {
"providerType": "SQLite",
"connectionString": "Data source=|datadirectory|documents/db/northwind.db3"
}
}
}
}
}
那么 Fireasy 将使用 default 的默认数据库实例来创建 EntityContext
对象。
2、重写构造函数
如果你需要定义两个不同的 EntityContext
,而每一个都绑定不同的数据库,此时就需要重写构造函数来指定使用哪一个数据库实例了。下面的示例中,DbContext1
使用 mssql 实例,DbContext2
使用 sqlite 实例。
public class DbContext1 : EntityContext
{
public DbContext1()
: base ("mssql")
{
}
}
public class DbContext2 : EntityContext
{
public DbContext2()
: base ("sqlite")
{
}
}
3、重写 OnConfiguring 方法
没有使用实例配置的情况下,你可以重写 OnConfiguring 方法来指定数据库提供者(可参考 数据库提供者)和数据库连接串。
public class DbContext : EntityContext
{
protected override void OnConfiguring(EntityContextOptionsBuilder builder)
{
builder.Options.Provider = SQLiteProvider.Instance; //指定数据库提供者
builder.Options.ConnectionString = "Data source=|datadirectory|documents/db/northwind.db3";
}
}
4、使用 Use* 扩展方法
你还可以使用 EntityContextOptionsBuilder
的扩展方法 Use* 来指定数据库连接串。它提供了类似的方法有:
- UseSqlServer: 使用 SqlServer 数据库
- UseMySql: 使用 MySql 数据库
- UseSQLite: 使用 SQLite 数据库
- UseOracle: 使用 Oracle 数据库
- UseFirebird: 使用 Firebird 数据库
- UsePostgreSql: 使用 PostgreSql 数据库
public class DbContext : EntityContext
{
protected override void OnConfiguring(EntityContextOptionsBuilder builder)
{
builder.UseSQLite("Data source=|datadirectory|documents/db/northwind.db3");
}
}
另外,在 .Net Core 程序的配置中,也可以在 Startup.ConfigureServices 方法里使用 Use*。
namespace demo
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddFireasy(Configuration);
services.AddEntityContext<DbContext>(builder =>
{
builder.UseSQLite("Data source=|datadirectory|documents/db/northwind.db3");
});
}
}
}
5、配置 EntityContextOptions
重写 EntityContext
构造函数,或重写 OnConfiguring 方法时,可以对 EntityContextOptions
进行设置。
EntityContextOptions
类的各属性含义如下:
- ConfigName:指定数据库配置实例的名称,如上面配置中的 mssql、sqlite、mysql 等等,如果不指定则使用默认实例。
- Provider:指定数据库提供者。
- ConnectionString:指定数据库连接串。
- NotifyEvents:指定是否开启持久化事件订阅。默认是关闭的。
- ValidateEntity:指定是否验证实体及属性。默认是开启的。
- AllowDefaultValue:指定是否分配默认值,当开启时,即使你没有对属性赋值,也会使用
PropertyMappingAttribute
指定的默认值为属性赋值。默认是开启的。 - IsolationLevel:指定数据库事务的默认隔离级别,默认为
IsolationLevel.ReadUncommitted
。 - CacheParsing:指定是否开启 lambda 表达式的解析缓存。
- CacheParsingTimes:指定解析缓存的有效时间。
- CacheExecution:指定是否开启查询结果集的缓存。
- CacheExecutionTimes:指定数据缓存的有效时间。
- LoadBehavior:指定关联属性的加载行为,默认是延迟加载。
public class DbContext : EntityContext
{
public DbContext()
: base (new EntityContextOptions { ConfigName = "mysql", NotifyEvents = true })
{
}
protected override void OnConfiguring(EntityContextOptionsBuilder builder)
{
builder.Options.NotifyEvents = false; //最终以这里的设置为准
}
}
EntityContextOptions
类的 Initializers 属性允许你添加初始化处理。它是实现 IEntityContextPreInitializer
接口的类型。Initializers 中默认添加了 RecompileAssemblyPreInitializer
类,它是负责编译所有实体代理类的处理器。除此之外,UseCodeFirst 和 UseOracleTrigger 方法也是应用了 IEntityContextPreInitializer
接口。
6、使用 CodeFirst 模式
重写 OnConfiguring 方法时,可以使用扩展方法 UseCodeFirst 来开启 CodeFirst 模式。它会使用 ITableGenerateProvider
扩展服务来检测实体的变动并生成相应的 DDL
执行到数据库中。开启 CodeFirst 后,应用的性能会有所下降。如下所示:
public class DbContext : EntityContext
{
protected override void OnConfiguring(EntityContextOptionsBuilder builder)
{
builder.UseCodeFirst();
}
}
7、Oracle 使用触发器赋值主键
Oracle 没有自增特性,只能使用序列值,默认下主键值是通 标识生成服务 得到序列值的,这就意味着新增操作被放弃(比如数据未通过验证),序列值仍然被消耗,这就导致了数据的不连贯。重写 OnConfiguring 方法时,可以使用扩展方法 UseOracleTrigger 来创建触发器以便实时得到序列值。如果 UseOracleTrigger 泛型方法指定具体的实体类时,则仅此实体类会应用这种机制,缺省情况下所有实体类都会被应用此机制。如下所示:
public class DbContext : EntityContext
{
protected override void OnConfiguring(EntityContextOptionsBuilder builder)
{
//builder.UseOracleTrigger(); //所有实体类都应用此机制
builder.UseOracleTrigger<Orders>(); //仅 Orders 会被应用
}
}
8、更改 IProvider 插件服务
在某些情况下,你可能需要更改 插件服务,此时可使用 UseServiceProvider 方法。比如,使用雪花算法来生成主键值,并使用自定义的语法插件,可参考以下所示代码:
public class MySnowflakeGenerator : SnowflakeGenerator
{
public MySnowflakeGenerator(IServiceProvider serviceProvider)
{
var configuration = serviceProvider.GetService<IConfiguration>();
//WorkerId放在配置文件 appsettings.json 中
WorkerId = Convert.ToInt32(configuration.GetSection("Snowflake:WorkerId").Value);
}
}
public class MyMsSqlSyntax : MsSqlSyntax
{
}
public class DbContext : EntityContext
{
protected override void OnConfiguring(EntityContextOptionsBuilder builder)
{
builder.UseProviderService(new MySnowflakeGenerator(builder.Options.ServiceProvider));
builder.UseProviderService<MyMsSqlSyntax>();
}
}
9、使用持久化环境
当你需要使用分表时,需要使用持久化环境添加变量。如下所示:
public class DbContext : EntityContext
{
protected override void OnConfiguring(EntityContextOptionsBuilder builder)
{
builder.UseEnvironment();
}
}