ef core 配置的值对象必须初始化问题

  在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,除非它们显式映射到与所有者不同的表
  • 拥有的实体类型的实例不能由多个所有者共享(这是一个已知的值对象方案,不能使用拥有的实体类型来实现)
 

 

原文地址:https://www.cnblogs.com/caiyangcc/p/12807328.html