FreeSql 教程 (三)實體特性

FreeSql 以 MIT 開源協(xié)議托管于 github:https://github.com/2881099/FreeSql

主鍵(Primary Key)

class Topic {
    [Column(IsPrimary = true)]
    public int Id { get; set; }
}

約定:

  • 當沒有指明主鍵時,命名為 id 的字段將成為主鍵;(不區(qū)分大小寫)

  • 當主鍵是 Guid 類型時,插入時會自動創(chuàng)建(有序、不重復(fù))的值,所以不需要自己賦值;(支持分布式)

自增(Identity)

class Topic {
    [Column(IsIdentity = true)]
    public int Id { get; set; }
}

約定:

  • 當沒有指明主鍵時,標記自增的成員將成為主鍵;

唯一鍵(Unique Key)、索引(Index)

[Index("uk_phone", "phone", true)]
[Index("uk_group_index", "group,index", true)]
[Index("uk_group_index22", "group, index22 desc", true)]
class AddUniquesInfo
{
    public Guid id { get; set; }
    public string phone { get; set; }

    public string group { get; set; }
    public int index { get; set; }
    public string index22 { get; set; }
}

第三個參數(shù) true 的時候是唯一鍵,false 的時候是普通索引。

數(shù)據(jù)庫類型(DbType)

class Topic {
    [Column(DbType = "varchar(128) NOT NULL")]
    public string Title { get; set; }
}

可以在類型上指定 NOT NULL,也可以通過 [Column(IsNullable = false)] 設(shè)置;

0.12.8 版本增加了 [Column(StringLength = 128)] 針對字符串的長度設(shè)置;

0.9.12 版本增加了對 MaxLength 特性的解析,上面的 varchar(128) 可改寫成:

class Topic {
    [MaxLength(128)]
    public string Title { get; set; }
}

當 string 長度 -1 時產(chǎn)生的映射如下:

MySql PostgreSQL SqlServer Oracle Sqlite MsAccess
text text varchar(max) nvarchar2(4000) text longtext

服務(wù)器時間(ServerTime)

class Topic {

    [Column(ServerTime = DateTimeKind.Utc, CanUpdate = false)]
    public DateTime CreateTime { get; set; }
    
    [Column(ServerTime = DateTimeKind.Utc)]
    public DateTime UpdateTime { get; set; }
}

v0.12.4 使用數(shù)據(jù)庫時間執(zhí)行插入數(shù)據(jù),注意:

1、一但設(shè)置了這個特性,插入的時候設(shè)置屬性值是無效的;

2、插入實體執(zhí)行成功后,實體的值還是 c# 時間;

v1.1 - ServerTime 特性,對 Update 方法時也能生效

其他參考:如果對時間精度要求不高,推薦下面的做法,先計算本地與服務(wù)器時間差距,再使用 Aop 統(tǒng)一處理:

var serverTime = fsql.Select<T>().Limit(1).First(a => DateTime.UtcNow);
var timeOffset = DateTime.UtcNow.Subtract(serverTime); //減去數(shù)據(jù)庫時間

fsql.Aop.AuditValue += new EventHandler<Aop.AuditValueEventArgs>((_, e) =>
{
    if (e.Column.Attribute.MapType.NullableTypeOrThis() == typeof(DateTime))
    {
        if (e.Value == null || (DateTime)e.Value == default(DateTime))
        {
            e.Value = DateTime.Now.Subtract(timeOffset); //使用本地時區(qū)保存
            return;
        }
    }
});

可空(Nullable)

class Topic {
    [Column(IsNullable = false)]
    public string Title { get; set; }
}

在不指定 DbType、IsNullable 時,F(xiàn)reeSql 提供默認設(shè)定,如:

  • int -> not null(不可為空)
  • int? -> null(可空)

一般在使用 string 類型時,才需要手工指明是否可空(string 默認可空);

忽略(Ignore)

class Topic {
    [Column(IsIgnore = true)]
    public string Title { get; set; }
}

當實體有屬性不需要映射的時候使用,內(nèi)部自動忽略了對象的映射;

當實體內(nèi)的屬性不是可接受的類型時,可以不用指定該特定,如下不必要的指定:

class Topic {
    [Column(IsIgnore = true)]
    public Topic Parent { get; set; }
}

樂觀鎖(RowVersion)

class Topic {
    public Guid id { get; set; }
    public string Title { get; set; }

    [Column(IsVersion = true)]
    public int Version { get; set; }
}

更新整個實體數(shù)據(jù)時,在并發(fā)情況下極容易造成舊數(shù)據(jù)將新的記錄更新。

樂觀鎖的原理,是利用實體某字段,如:long version,更新前先查詢數(shù)據(jù),此時 version 為 1,更新時產(chǎn)生的 SQL 會附加 where version = 1,當修改失敗時(即 Affrows == 0)拋出異常。

每個實體只支持一個樂觀鎖屬性。

適用 SetSource 更新,無論使用什么方法更新 version 的值都會增加 1

自定義類型映射(MapType)

class EnumTestMap {
    public Guid id { get; set; }

    [Column(MapType = typeof(string))]
    public ToStringMapEnum enum_to_string { get; set; }
    [Column(MapType = typeof(string))]
    public ToStringMapEnum? enumnullable_to_string { get; set; }

    [Column(MapType = typeof(int))]
    public ToStringMapEnum enum_to_int { get; set; }
    [Column(MapType = typeof(int?))]
    public ToStringMapEnum? enumnullable_to_int { get; set; }

    [Column(MapType = typeof(string))]
    public BigInteger biginteger_to_string { get; set; }
    [Column(MapType = typeof(string))]
    public BigInteger? bigintegernullable_to_string { get; set; }
}
public enum ToStringMapEnum { 中國人, abc, 香港 }

BigInteger 也可以映射使用,但請注意:僅僅是 CURD 方便, Equals == 判斷可以使用,無法實現(xiàn) + - * / 等操作;

v0.9.15 版本還可以將值對象映射成 typeof(string),安裝擴展包:

dotnet add package FreeSql.Extensions.JsonMap

fsql.UseJsonMap(); //開啟功能

class TestConfig
{
    public int clicks { get; set; }
    public string title { get; set; }
}
[Table(Name = "sysconfig")]
public class S_SysConfig
{
    [Column(IsPrimary = true)]
    public string Name { get; set; }

    [JsonMap]
    public TestConfig Config { get; set; }
}

字段位置(Position)

適用場景:當實體類繼承時,CodeFirst創(chuàng)建表的字段順序可能不是想要的,通過該特性可以設(shè)置順序。

創(chuàng)建表時指定字段位置,如:[Column(Position = 1],可為負數(shù)即反方向位置;

可插入(CanInsert)、可更新(CanUpdate)

該字段是否可以插入或更新,默認值true,指定為false插入或更新時該字段會被忽略。

當指明了 InsertColumn/UpdateColumns 等方法時,該特性作用可能失效。例如 CanInsert = false 時,又指明了 InsertColumns 該屬性,則仍然會插入。

名稱

FreeSql 默認使用實體的類名,或?qū)傩悦c數(shù)據(jù)庫映射,也可以指定映射的名稱;

指定實體的表名,指定 Name 后,實體類名變化不影響數(shù)據(jù)庫對應(yīng)的表。FreeSql盡量支持了對多數(shù)據(jù)庫或schema支持,不防試試指定表名為:其他數(shù)據(jù)庫.表名,不同數(shù)據(jù)庫的指定方式有差異,這一點以后深入解答。

[Table(Name = "db2.tb_topic111")]
class Topic {
  //...
}

注意:盡量不要使用帶點的表名,只有 MySql/Sqlite 對此類表名支持 CodeFirst。但是它不影響 CRUD 功能,使用 [Table(Name = "`sys.config`")] 解決

指定實體的表名,修改為實體類名。指定數(shù)據(jù)庫舊的表名,修改實體命名時,同時設(shè)置此參數(shù)為修改之前的值,CodeFirst才可以正確修改數(shù)據(jù)庫表;否則將視為【創(chuàng)建新表】。

[Table(OldName = "Topic")]
class Topic2 {
  //...
}

實體的屬性也有相同的功能,[Column(Name = "xxx")]

禁用遷移

IFreeSql.CodeFirst.IsAutoSyncStructure 可設(shè)置全局【自動遷移結(jié)構(gòu)】功能,也可通過 FreeSqlBuilder.UseAutoSyncStructure(true) 創(chuàng)建 IFreeSql 的時候設(shè)置功能。

當【實體類】對應(yīng)的是數(shù)據(jù)庫【視圖】或者其他時,可通過 [Table(DisableSyncStructure = true)] 禁用指定的實體遷移操作。

[Table(DisableSyncStructure = true)]
class ModelDisableSyncStructure {
    [Column(IsPrimary = false)]
    public int pkid { get; set; }
}

備注

FreeSql CodeFirst 支持將 c# 代碼內(nèi)的注釋,遷移至數(shù)據(jù)庫的備注。先決條件:

1、實體類所在程序集,需要開啟 xml 文檔功能;

2、xml 文件必須與程序集同目錄,且文件名:xxx.dll -> xxx.xml;

系列文章導(dǎo)航

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 第三章 數(shù)據(jù)庫系統(tǒng) 3.1 數(shù)據(jù)庫管理系統(tǒng)的類型 通常有多個分類標準。如按數(shù)據(jù)模型分類、按用戶數(shù)分類、按數(shù)據(jù)庫分布...
    步積閱讀 3,117評論 0 7
  • 索引 數(shù)據(jù)庫中的查詢操作非常普遍,索引就是提升查找速度的一種手段 索引的類型 從數(shù)據(jù)結(jié)構(gòu)角度分 1.B+索引:傳統(tǒng)...
    一凡呀閱讀 3,217評論 0 8
  • 數(shù)據(jù)庫的基本是概念名詞解釋: 數(shù)據(jù)庫名詞解釋 元組:可以理解為表的每一行就是一個元組 候選碼:若關(guān)系中的某一屬性組...
    杰倫哎呦哎呦閱讀 1,238評論 0 6
  • 1、native-重點 native由hibernate根據(jù)使用的數(shù)據(jù)庫自行判斷采用identity、hilo、s...
    宇宙小神特別萌閱讀 2,847評論 0 1
  • 劫鞋閱讀 185評論 0 0

友情鏈接更多精彩內(nèi)容