DDD/ABP/EF Core 实现值对象Value Object

35 篇文章 0 订阅
22 篇文章 0 订阅

有一说一DDD真tM抽象 :<, 看一遍真是看不懂。

简单理解值对象和实体的区别:

1. 实体具有唯一标识符,就是主键

2. 值对象无法单独存在,一定是依附于一个实体

举个栗子🌰, 地址的三个属性必须同时存在,缺少一个地址属性就没意义了。

class girlfriend
{
    string height;
    string weight;
    string location;
}

class location
{
    string country;
    string city;
    string street;    
}

那么深入一些:值对象存在的意义 是 把领域知识 放到类的定义中。 

实现方式有2种 

1. “从属实体类型(owned entities)”:使用Fluent API中的OwnsOne等方法来配置。

2、在EF Core中,实体的属性可以定义为枚举类型,枚举类型的属性在数据库中默认是以整数类型来保存的。对于直接操作数据库的人员来讲,0、1、2这样的值没有“CNY”(人民币)、“USD”(美元)、“NZD”(新西兰元)等这样的字符串类型值可读性更强。EF Core中可以在Fluent API中用HasConversion<string>()把枚举类型的值配置成保存为字符串。(看图二)

 方式2

 建议:值对象 定义为 record类型

​class ​是主要常用类型,属于引用类型,可以继承,可以多态,还可以定义抽象类。我们用的最多的。在进行两个类对象==操作时,默认比较的是对象的引用地址是否相等。


​struct ​是很早C语言就开始使用的数据结构,一般用于简单的数据,不能继承和多态,属于值类型,比较时,默认是进行类型相同并且里面的字段值相等。可以对每个成员变量进行比特位的控制,用于与C程序库中的数据类型进行互相通信时会使用,比如PInvoke时候就常用。


​​record ​​新增的类型,默认==操作是进行类型判断和成员值全部相等,也属于值类型。默认初始化之后,其成员数据是无法修改的。可以使用with快速方便的在复制一个副本时修改其中某些成员的值。但是其实现的复制是潜复制。
 

方式1

栗子:将坐标(经纬度)定义为值对象,设置构造函数,好处是在构造中就可以进行校验

这就是领域知识封装到一个类里面 !因为其他人是不知道经纬度的合法数值的!

record Geo{
	public double Longitude { get; init; }
	public double Latitude { get; init; }
	public Geo(double longitude, double latitude)
	{
		if(longitude<-180||longitude>180)
			throw new ArgumentException("longitude invalid");
		if (latitude < -90 || latitude > 90)
			throw new ArgumentException("longitude invalid");
		this.Longitude = longitude;
		this.Latitude = latitude;
	}

注意,Location是一个从属实体属性 ,所以需要配置

看,配置完之后,数据库存储时候会将Location展开为2个列,并且附加到shop表内。

再次复习一下为什么两个 构造器 一个private 一个public!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

董厂长

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值