1. 程式人生 > 其它 >DDD之EFCore操作實體屬性和實現充血模型

DDD之EFCore操作實體屬性和實現充血模型

1. DDD之EFCore操作實體屬性和實現充血模型

1.1 EFCore操作實體屬性

(1)物件操作實體屬性會呼叫get,set方法

(2)基於效能和對特殊功能支援的考慮,EF Core在讀寫屬性的時候,如果可能,它會直接跳過get、set,而直接操作真正儲存屬性值的成員變數

(3)EF Core在讀寫實體物件的屬性時,會查詢屬性對應的成員變數,如果能找到,EF Core會直接讀寫這個成員變數的值,而不是通過set和get程式碼塊來讀寫。

(4)EF Core會嘗試按照命名規則去直接讀寫屬性對應的成員變數,只有無法根據命名規則找到對應成員變數的時候,EF Core才會通過屬性的get、set程式碼塊來讀寫屬性值。可以在FluentAPI中通過UsePropertyAccessMode()方法來修改預設的這個行為。

1.2 EFCore實現充血模型

User

public class User
{
    //屬性是隻讀的或者只能被內部的程式碼修改。
    //把屬性的set定義為private或者init,然後通過構造方法為這些屬性賦予初始值。
    public int Id { get; init; }

    public DateTime CreatedDateTime { get; init; }

    public string UserName { get; private set; }

    public int Credit { get; private set; }

    //把私有成員變數對映到資料表中的列。
    //builder.Property("成員變數名")
    private string? passwordHash;

    //有的屬性只讀的,也就是它的值是從資料庫中讀取出來的,但是我們不能修改屬性值。
    //在配置實體類的程式碼中,使用HasField(“成員變數名”)來配置屬性
    private string? remark;
    public string? Remark 
    {
        get { return remark; }
    }

    //有的屬性不需要對映到資料列,僅在執行時被使用。
    //Ignore()來配置忽略這個屬性。
    public string? Tag { get; set; }



    //造方法中的引數的名字和屬性的名字一致。

    public User(string userName, DateTime createdDateTime, int credit)
    {
        this.UserName = userName;
        this.CreatedDateTime = createdDateTime;
        this.Credit = credit;
    }

    //無參構造方法定義為private。
    //EFCore使用
    /*
    private User() { }


    //如果建構函式和屬性名稱不匹配
    public User(string un, DateTime time, int c)
    {
        this.UserName = un;
        this.CreatedDateTime = time;
        this.Credit = c;
    }
    */

}

UserConfig

public class UserConfig : IEntityTypeConfiguration<User>
{
    public void Configure(EntityTypeBuilder<User> builder)
    {
        builder.ToTable("T_Users");
        builder.Property(u => u.UserName).IsRequired().HasMaxLength(50);
        //builder.Property把私有成員變數對映到資料表中的列。
        builder.Property("passwordHash").IsRequired().HasMaxLength(100);
        //屬性是隻讀的,也就是它的值是從資料庫中讀取出來的,但是我們不能修改屬性值。
        //使用HasField(“成員變數名”)來配置屬性
        builder.Property(u => u.Remark).HasField("remark").HasMaxLength(100); ;
        //builder.Ignore有的屬性不需要對映到資料列,僅在執行時被使用。
        builder.Ignore(u => u.Tag);//特徵五
    }
}

(1)屬性是隻讀的或者只能被內部的程式碼修改。

實現:把屬性的set定義為private或者init,然後通過構造方法為這些屬性賦予初始值。

(2)定義有引數的構造方法。

實現:

  • 無參構造方法定義為private。
  • 實體類中不定義無參構造方法,只定義有意義的有參構造方法,但是要求構造方法中的引數的名字和屬性的名字一致。

(3)有的成員變數沒有對應屬性,但是這些成員變數需要對映為資料表中的列,也就是我們需要把私有成員變數對映到資料表中的列。

實現:

builder.Property("成員變數名")

(4)有的屬性只讀的,也就是它的值是從資料庫中讀取出來的,但是我們不能修改屬性值。

在配置實體類的程式碼中,使用HasField(“成員變數名”)來配置屬性。

(5)有的屬性不需要對映到資料列,僅在執行時被使用。

使用Ignore()來配置忽略這個屬性。

(6)檢視資料庫

執行命令add-mirgration 、update-database