1. 程式人生 > >如何使用EF優雅的配置一對一的關系

如何使用EF優雅的配置一對一的關系

entity use stat api 是什麽 name 基礎 jin chang

在這兩天的時間已經有兩位同事問到EF(Code First)如何配置一對一的關系,這個說難也不難,說簡單吧,一旦設計跑偏那麽在Coding的過程中將會很痛苦。

先舉個很簡單的例子,兩個類User和Profile,User裏面存在用戶的基本信息比如郵箱和密碼,Profile裏面存放用戶的個人資料。

public class User
{
    public int Id { get; set; }
    public string Email { get; set; }
    public string Password { get; set; }
    public virtual Profile Profile { get; set; }
}

public class Profile
{
    public int Id { get; set; }
    public string Name { get; set; }
    public Gender Gender { get; set; }
    public string Phone { get; set; }
    public string Address { get; set; }
    public virtual User User { get; set; }
}

上面的代碼應該是直接了當的。透過領域模型應該能充分描述出User和Profile的業務。分析:對於一個User來說只能有一個Profile(一對一),反過來對於一個Profile來說只能對應一個User(一對一),而且也必須有一個User。下面是通過fluent api做一些映射

public class UserMapping : EntityTypeConfiguration<User>
{
    public UserMapping()
    {
        ToTable("tb_User");
    }
}

public class ProfileMapping : EntityTypeConfiguration<Profile>
{
    public ProfileMapping()
    {
        ToTable("tb_Profile");

        HasKey(u => u.Id)
            .HasRequired(u => u.User)       // 對於一個Profile來說必須有一個User否則Profile無家可歸
            .WithOptional(u => u.Profile)   // 同事一個User對應一個Profile 非必須
            .WillCascadeOnDelete(false);    // 不需要級聯刪除
    }
}

上面的代碼也應該也是直接了當的。那麽這樣生成的數據庫結構是什麽樣的呢?約束又是什麽樣的呢?又是否符合我們的業務需求
技術分享技術分享

User表沒有什麽問題,Profile的ID字段不單單是一個主鍵,同時也是一個外鍵。我們回到具體的業務中來。當我插入一條User數據的時候要不要插入Profile數據呢?其實是都可以的,如果同時插入的話,User和Profile應該是一起往前走的,而且User的ID和Profile的ID是一樣的。那如果插入User的時候不插入Profile呢,其實也沒有問題,詳細的說明:
假如我插入兩條User數據,User表會有兩條數據,ID分別為1和2。Profile表為空,沒有數據。2用戶有一天回過頭來想完善自己的個人詳細信息,插進去的Profile數據ID應該為2,後來1用戶也來完善自己的個人資料,這個時候插入的Profile數據ID為1(雖然2用戶先完善的,2用戶的ProfileID還是2,1用戶的ProfileID還是1)。

static void Main(string[] args)
{
    DemoDbContext db = new DemoDbContext();
    var user = db.Users.SingleOrDefault(u => u.Id == 2);
    Profile profile = new Profile
    {
        Address = "beijing"
    };
    user.Profile = profile;
    db.SaveChanges();
}

順便對領域模型嘮叨幾句:
領域模型是領域驅動設計中最重要的對象,它們是描述我們業務的對象,應該最大力度保持幹凈,整潔。作為一名開發人員應該多花點時間放在領域的設計上。然而領域的設計應該是和領域專家(產品經理)強度溝通的情況下去完成設計的。比如要做一款財務軟件,程序員怎麽可能對財務非常精通,都是和財務專家或懂財務的人溝通的基礎上去完成我們的領域設計。所以在公司中應確保最好,最有經驗的開發人員分配到領域相關的任務上去。

如何使用EF優雅的配置一對一的關系