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

     

  • 相关阅读:
    Python中Linux开发的常识
    Python GUI编程(Tkinter)
    linux文本编辑器教学
    WordCloud安装
    怎么安装wordcloud
    java内功 ---- jvm虚拟机原理总结,侧重于GC
    spring源码分析(二)Aop
    spring源码分析(一)IoC、DI
    java内部类技术提炼
    java自定义注解实现前后台参数校验
  • 原文地址:https://www.cnblogs.com/caiyangcc/p/12807328.html
Copyright © 2020-2023  润新知