-
Notifications
You must be signed in to change notification settings - Fork 890
CodeFirst
FreeSql 支持 CodeFirst 迁移结构至数据库,这应该是(O/RM)必须标配的一个功能。
与其他(O/RM)不同FreeSql支持更多的数据库特性,而不只是支持基础的数据类型,这既是优点也是缺点,优点是充分利用数据库特性辅助开发,缺点是切换数据库变得困难。不同程序员的理念可能不太一致,作为功能库FreeSql支持到了极致,至于是否使用是项目组技术衡量的另一个问题。
尽管多种数据库适配逻辑非常复杂,FreeSql始终秉承优化程序开发习惯的原则尽量去实现,中间碰到了一些非技术无法攻克的难题,比如数据库的自定义类型,和实体类本身就是一种冲突,为了减少使用成本,诸如此类的数据库功能没有得到支持。
IFreeSql fsql = new FreeSql.FreeSqlBuilder()
.UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=10")
.UseAutoSyncStructure(true) //自动同步实体结构【开发环境必备】
.Build();
实体&表对比 | 添加 | 改名 | 删除 |
---|---|---|---|
√ | √ | X |
实体属性&字段对比 | 添加 | 修改可空 | 修改自增 | 修改类型 | 改名 | 删除 |
---|---|---|---|---|---|---|
√ | √ | √ | √ | √ | X |
为了保证安全,不提供删除字段
FreeSql提供两种CodeFirst移迁方法,自动和手动。
自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后迁移执行创建或修改。
fsql.CodeFirst.IsAutoSyncDataStructure = true;
此功能默认为开启状态,发布正式环境后,请修改此设置。
虽然【自动同步实体结构】功能开发非常好用,但是有个坏处,就是数据库后面会很乱,没用的字段可能一大堆。
提供接口方法实现对比实体,与数据库中的变化部分,返回SQL语句。
var t1 = mysql.CodeFirst.GetComparisonDDLStatements<Topic>();
class Topic {
[Column(IsIdentity = true, IsPrimary = true)]
public int Id { get; set; }
public int Clicks { get; set; }
public string Title { get; set; }
public DateTime CreateTime { get; set; }
public ushort fusho { get; set; }
}
CREATE TABLE IF NOT EXISTS `cccddd`.`Topic` (
`Id` INT(11) NOT NULL AUTO_INCREMENT,
`Clicks` INT(11) NOT NULL,
`Title` VARCHAR(255),
`CreateTime` DATETIME NOT NULL,
`fusho` SMALLINT(5) UNSIGNED NOT NULL,
PRIMARY KEY (`Id`)
) Engine=InnoDB CHARACTER SET utf8;
提供接口方法实现同步结构
var t2 = fsql.CodeFirst.SyncStructure<Topic>();
//同步实体类型到数据库
指定实体的表名,指定 Name 后,实体类名变化不影响数据库对应的表。FreeSql尽量支持了对多数据库或schema支持,不防试试指定表名为:其他数据库.表名,不同数据库的指定方式有差异,这一点以后深入解答。
[Table(Name = "db2.tb_topic111")]
class Topic {
//...
}
无指定实体的表名,修改为实体类名。指定数据库旧的表名,修改实体命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库表;否则将视为【创建新表】。
[Table(OldName = "Topic")]
class Topic2 {
//...
}
ALTER TABLE `cccddd`.`Topic` RENAME TO `cccddd`.`Topic2`;
修改字段类型,把 Id 类型改为 uint,Title 类型改为 varchar(128)。
ALTER TABLE `cccddd`.`Topic2` MODIFY `Id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT;
[Column(DbType = "varchar(128)")]
public string Title { get; set; }
ALTER TABLE `cccddd`.`Topic2` MODIFY `Title2` VARCHAR(128);
指定属性的字段名,这样指定后,修改实体的属性名不影响数据库对应的列。
[Column(Name = "titl2")]
public string Title { get; set; }
无指定属性的字段名,修改为属性名,指定数据库旧的列名,修改实体属性命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库字段;否则将视为【新增字段】。
[Column(OldName = "Title2")]
public string Title { get; set; }
ALTER TABLE `cccddd`.`Topic2` CHANGE COLUMN `Title2` `Title` VARCHAR(255);
fsql.CodeFirst
.ConfigEntity<TestFluenttb1>(a => {
a.Name("xxdkdkdk1").SelectFilter("a.Id22 > 0");
a.Property(b => b.Id).Name("Id22").IsIdentity(true);
a.Property(b => b.name).DbType("varchar(100)").IsNullable(true);
})
.ConfigEntity<TestFluenttb2>(a => {
a.Name("xxdkdkdk2").SelectFilter("a.Idx > 0");
a.Property(b => b.Id).Name("Id22").IsIdentity(true);
a.Property(b => b.name).DbType("varchar(100)").IsNullable(true);
});
只能在程序初始化执行,否则配置可能不生效。原因:FreeSql在使用实体的初次会缓存,以便提升后续的运行性能,若上段配置代码在缓存之后执行则不能生效。打个比方飞机起飞了,能马上降落吗?
csharp | MySql | SqlServer | PostgreSQL | Oracle | Sqlite |
---|---|---|---|---|---|
bool | bool? | bit(1) | bit | bool | number(1) | boolean |
sbyte | sbyte? | tinyint(3) | smallint | int2 | number(4) | smallint |
short | short? | smallint(6) | smallint | int2 | number(6) | smallint |
int | int? | int(11) | int | int4 | number(11) | integer |
long | long? | bigint(20) | bigint | int8 | number(21) | integer |
byte | byte? | tinyint(3) unsigned | tinyint | int2 | number(3) | int2 |
ushort | ushort? | smallint(5) unsigned | int | int4 | number(5) | unsigned |
uint | uint? | int(10) unsigned | bigint | int8 | number(10) | decimal(10,0) |
ulong | ulong? | bigint(20) unsigned | decimal(20,0) | numeric(20,0) | number(20) | decimal(21,0) |
double | double? | double | float | float8 | float(126) | double |
float | float? | float | real | float4 | float(63) | float |
decimal | decimal? | decimal(10,2) | decimal(10,2) | numeric(10,2) | number(10,2) | decimal(10,2) |
Guid | Guid? | char(36) | uniqueidentifier | uuid | char(36 CHAR) | character(36) |
TimeSpan | TimeSpan? | time | time | time | interval day(2) to second(6) | bigint |
DateTime | DateTime? | datetime | datetime | timestamp | timestamp(6) | datetime |
DateTimeOffset | DateTimeOffset? | - | - | datetimeoffset | timestamp(6) with local time zone | - |
Enum | Enum? | enum | int | int4 | number(16) | mediumint |
FlagsEnum | FlagsEnum? | set | bigint | int8 | number(32) | bigint |
byte[] | varbinary(255) | varbinary(255) | bytea | blob | blob |
string | varchar(255) | nvarchar(255) | varchar(255) | nvarchar2(255) | nvarchar(255) |
MygisPoint | point | - | - | - | - |
MygisLineString | linestring | - | - | - | - |
MygisPolygon | polygon | - | - | - | - |
MygisMultiPoint | multipoint | - | - | - | - |
MygisMultiLineString | multilinestring | - | - | - | - |
MygisMultiPolygon | multipolygon | - | - | - | - |
BitArray | - | - | varbit(64) | - | - |
NpgsqlPoint | NpgsqlPoint? | - | - | point | - | - |
NpgsqlLine | NpgsqlLine? | - | - | line | - | - |
NpgsqlLSeg | NpgsqlLSeg? | - | - | lseg | - | - |
NpgsqlBox | NpgsqlBox? | - | - | box | - | - |
NpgsqlPath | NpgsqlPath? | - | - | path | - | - |
NpgsqlPolygon | NpgsqlPolygon? | - | - | polygon | - | - |
NpgsqlCircle | NpgsqlCircle? | - | - | circle | - | - |
(IPAddress Address, int Subnet) | (IPAddress Address, int Subnet)? | - | - | cidr | - | - |
IPAddress | - | - | inet | - | - |
PhysicalAddress | - | - | macaddr | - | - |
NpgsqlRange<int> | NpgsqlRange<int>? | - | - | int4range | - | - |
NpgsqlRange<long> | NpgsqlRange<long>? | - | - | int8range | - | - |
NpgsqlRange<decimal> | NpgsqlRange<decimal>? | - | - | numrange | - | - |
NpgsqlRange<DateTime> | NpgsqlRange<DateTime>? | - | - | tsrange | - | - |
PostgisPoint | - | - | geometry | - | - |
PostgisLineString | - | - | geometry | - | - |
PostgisPolygon | - | - | geometry | - | - |
PostgisMultiPoint | - | - | geometry | - | - |
PostgisMultiLineString | - | - | geometry | - | - |
PostgisMultiPolygon | - | - | geometry | - | - |
PostgisGeometry | - | - | geometry | - | - |
PostgisGeometryCollection | - | - | geometry | - | - |
Dictionary<string, string> | - | - | hstore | - | - |
JToken | - | - | jsonb | - | - |
JObject | - | - | jsonb | - | - |
JArray | - | - | jsonb | - | - |
数组 | - | - | 以上所有类型都支持 | - | - |
以上类型和长度是默认值,可手工设置,如 string 属性可指定 [Column(DbType = "varchar(max)")]