在DDD里面 值對象是將一個值 用對象的方式進行表述,來表達一個具體的固定不變的概念。ef core 是 owned實現值對象。
pubic class Student : Entity<int> { public string Name { get; private set; } public ModifyUser ModifyUser { get; private set; } public Student(string name, ModifyUser modifyUser) { this.Name = name; this.ModifyUser = modifyUser; } } // 不建議用特性指定,這里只是為了演示 [Owned] public class ModifyUser : ValueObject { public string Name { get; private set; } public string Tel { get; private set; } public ModifyUser(string name, string tel ) { this.Name = name; this.Tel = tel; } protected override IEnumerable<object> GetAtomicValues() { yield return Name + Tel; } }
這里好像沒什么問題,但是在業務里當創建Student時我好像不應該傳入修改者的值對象,我們來修改下Studnet的代碼:
pubic class Student : Entity<int> { public string Name { get; private set; } public ModifyUser ModifyUser { get; private set; } private Student(string name) { this.Name = name; } private Student(string name, ModifyUser modifyUser) { this.Name = name;
this.ModifyUser = modifyUser; } // 當執行新增時這里運行時會報錯 public static Student CreateFactory(string name) { return new Student(name); } public static Student UpdateFactory(string name, ModifyUser modifyUser) { return new Student(name, modifyUser); } }
這里會報錯的原因是 在邏輯中我們是正確的,新增時我們不應該有修改者的信息,但是在實現時我們沒有考慮到技術上的問題,創建時值對象為null,
它是一個整體,不能為null 這個修改者可以為null,應該體現在這一句
yield return Name + Tel; 這代表值對象的整體的唯一標識
, 我們可以在CreateFactory 給 默認ModifyUser 無參構造函數 但是這樣ModifyUser 就暴露出了一個無參構造函數,別人可能不太理解是什么意思,我們的解決辦法是
pubic class Student : Entity<int> { public string Name { get; private set; } public ModifyUser ModifyUser { get; private set; } private Student(string name) { this.ModifyUser = ModifyUser.Empty; this.Name = name; } private Student(string name, ModifyUser modifyUser) { this.Name = name; this.ModifyUser = modifyUser; } public static Student CreateFactory(string name) { return new Student(name); } public static Student UpdateFactory(string name, ModifyUser modifyUser) { return new Student(name, modifyUser); } } // 不建議用特性指定,這里只是為了演示 [Owned] public class ModifyUser : ValueObject { public static readonly ModifyUser Empty = new ModifyUser(); public string Name { get; private set; } public string Tel { get; private set; } private ModifyUser() { } public ModifyUser(string name, string tel ) { this.Name = name; this.Tel = tel; } protected override IEnumerable<object> GetAtomicValues() { yield return Name + Tel; } }
這樣雖然可以,但總感覺還是有問題!期待大佬們幫忙解惑!
補充:官方介紹
限制
其中一些限制對於擁有的實體類型的工作方式很重要,但其他一些限制是我們可以在未來版本中刪除的限制:
按設計限制
- 不能
DbSet<T>
為擁有的類型創建 - 不能
Entity<T>()
對擁有的類型調用ModelBuilder
當前缺陷
- 擁有的實體類型不能具有繼承層次結構
- 引用導航到擁有的實體類型不能為 null,除非它們顯式映射到與所有者不同的表
- 擁有的實體類型的實例不能由多個所有者共享(這是一個已知的值對象方案,不能使用擁有的實體類型來實現)