注意:我以 C# 为例,但在 Java 和许多其他语言中问题几乎相同。
假设您实现了一个值对象(如M. Fowler 的值对象模式)并且它有一些可为空的字段:
class MyValueObject
{
// Nullable field (with public access to keep the example short):
public string MyField;
}
Run Code Online (Sandbox Code Playgroud)
然后,当覆盖 Equals() 时,您如何处理两个值对象的 MyField 都设置为 null 的情况?它们是否相等?
在 C# 中,平等对待它们似乎很明显,因为:
这是当您使用 C# 结构而不是类并且不覆盖 Equals() 时 Equals() 的行为。
以下表达式为真:
null == null
object.ReferenceEquals(null, null)
object.Equals(null, null)
Run Code Online (Sandbox Code Playgroud)然而,在 SQL 中(至少在 SQL Server 的方言中),NULL = NULL是假的,反之则NULL is NULL是真的。
我想知道在使用 O/R 映射器(在我的例子中是 NHibernate)时需要什么样的实现。如果你实现了“自然”的 C# 相等语义,当 O/R 映射器将它们映射到数据库时会不会有任何不良影响?
或者也许允许值对象中的可为空字段无论如何都是错误的?
让\xc2\xb4s 假设我们\xc2\xb4 在系统中有两个域:Orderdomain 和Customerdomain。
\n\n这两个域都相当复杂且庞大,因此将它们合并到一个域中并不是一种选择。
\n\n但他们之间存在业务关系。在每个订单上,客户充当订购者。
\n\n我脑子里至少有三个解决方案。
\n\n将 customerId 作为原始类型存储在 Order 和 Customer 上。
创建两个值对象 OrderDomain.CustomerId 和 CustomerDomain.CustomerId。确保可以比较这些类型的相等性。
使用 valeobject CustomerId 创建第三个组件“SharedValueObjects”,并在两个域中使用该类型
哪一个是首选,或者您能想出第四个更好的吗?
\n我有一个值对象LoginAuth,其中包含User我的辅助登录系统的身份验证数据。
对于每个登录User,都可以选择是否选择辅助登录。因此User实体并不保存LoginAuth值对象,而是LoginAuth值对象包含User它所属的实体。
由于我的数据库已标准化,因此我将此值对象存储在一个单独的表中,其中 是user_id主键(以确保唯一性)。
正如您所看到的,我的值对象并不存在于实体内部,而是独立存在,但它确实包含它所属的实体。我的问题是:
价值对象可以在不存在于实体内部的情况下存在吗?
也许这需要是一个实体?
每个都LoginAuth应该是唯一的(每个 只User允许有一个唯一LoginAuth),因此不会有任何与此 VO 相同的内容。
注意:我的域不包含此登录系统的应用逻辑。只是它应该处理的数据。它的应用逻辑驻留在我的模型层的应用层中。
在我的域中,每个域实体可能有许多值对象。我创建了价值对象来表示金钱、重量、数量、长度、体积、百分比等。
这些值对象中的每一个都包含一个数值和一个度量单位。例如 money 包含货币价值和货币 ($, euro,...) , weight 包含数值和重量单位(kilo, pound, ...)
在用户界面中,这些也并排显示:字段名称、其值后跟其随附单元,通常在属性面板中。域实体具有向 UI 公开的等效 DTO。
我一直在寻找将 DTO 内的值对象传输到 UI 的最佳方法。
我已经进行了深入搜索,但似乎没有其他问题可以完全解决这个问题。非常感谢任何建议!
编辑:在 UI 中,值和单位都可以更改并发送回域进行更新。
我有一个价值对象-金钱和ExchangeRatio。我想使用ExchangeRatio将一种货币转换为另一种。因此,在Value Object ExchangeRatio上构建转换行为是一件好事,如下所示:
ExchangeRatio.Convert(Money)返回钱。
还是应该将其委托给某些域服务?换句话说,我可以在不改变其状态但具有某种逻辑,数学或其他不同对象创建方式(基于其状态)的价值对象上构建行为吗?
EF 6(代码优先)是否支持复杂类型集合(Value Object集合)映射?我知道它支持复杂类型,但还没有找到一个我们有一组复杂类型的例子.
例如,假设您有一个名为Student的实体,该实体具有一组联系人.对于NH,我可以简单地说学生有一组联系人,而联系人是一个组件(相当于ef中的复杂类型).这可以通过EF完成而不改变与实体的联系吗?
c# domain-driven-design entity-framework value-objects complextype
在创建聚合时,我们是否应该在聚合中创建值对象,或者我们应该将已创建的值对象传递给ctor或factory.
public Booking(DateTime arrivalDate, DateTime departureDate)
{
this.ArrivalAndDepartureinformation = new ArrivalAndDepartureInfo(arrivalDate, departureDate);
}
Run Code Online (Sandbox Code Playgroud)
要么
public Booking(ArrivalAndDepartureinformation arrivalAndDepartureInfo)
{
this.ArrivalAndDepartureinformation = arrivalAndDepartureInfo;
}
Run Code Online (Sandbox Code Playgroud) 学习DDD,在我们的应用中,有三个聚合根,不同类型的表单,所有这些都需要上传一些PDF。这些 pdf 上传有一些元数据,比如上传者和上传时间等,附加到它上面,以便它们存储在自己的表中。
我的问题是这个 PDF 是否应该建模为值对象、实体或聚合根。
对我来说,它看起来像一个名为“附件”的实体,但是这个实体应该被所有聚合根共享,只有类型而不是实例。在多个根中使用相同的实体类型是否允许实践,如果是,那么模型的哪一部分应该负责创建这个实体。
class Attachment{
Java.io.File pdf;
Date attachedOn;
.....
//no operation for this class
}
@AggregateRoot
class DocumentA {
Set<Attachment> attachments;
Set<DocumentB> supportingDocumentsB;
Set<DocumentA> supportingDocumentsA;
.... //other properties unique to DocumentA
attach(Attachment a);
detach(Attachment a);
addSupportingDocumentA(DocumentA doc);
removeSupportingDocumentA(DocumentA doc);
addSupportingDocumentB(DocumentB doc);
removeSupportingDocumentB(DocumentB doc);
.... //other operations unique to DocumentA
}
@AggregateRoot
class DocumentB {
Set<Attachment> attachments;
Set<DocumentB> supportingDocumentsB;
Set<DocumentA> supportingDocumentsA;
.... //other properties unique to DocumentB
attach(Attachment a);
detach(Attachment a);
addSupportingDocumentA(DocumentA doc);
removeSupportingDocumentA(DocumentA doc); …Run Code Online (Sandbox Code Playgroud) 我有一个具有值对象的实体,该值对象具有另一个值对象.我的问题是,在更新实体和值对象时,具有父值对象的实体会更新,但子值对象不会更新.请注意,我使用的是最新版本的Entity Framework Core 2.1.0-rc1-final,这是父实体Employee
public class Employee : Entity
{
public string FirstName { get; private set; }
public string LastName { get; private set; }
public string Email { get; private set; }
public Address Address { get; private set; }
}
Run Code Online (Sandbox Code Playgroud)
这是父值对象Address
public class Address : ValueObject<Address>
{
private Address() { }
public Address(string street, string city, string state, string country, string zipcode, GeoLocation geoLocation)
{
Street = street;
City = city;
State = state;
Country = country; …Run Code Online (Sandbox Code Playgroud) c# value-objects entity-framework-core entity-framework-core-2.1
考虑这些简单的类。它们属于具有领域驱动设计 (DDD) 原则的简单应用程序,因此每个 Entity 和 ValueObject 通过构造函数接收其属性值,同时隐藏默认的无参数构造函数。属性也将是只读的。
public class MyClass
{
public Guid Id {get;}
public ValueObject ValueObject1 {get;}
public ValueObject ValueObject2 {get;}
public MyClass(ValueObject valueObject1, ValueObject valueObject2)
{
ValueObject1 = valueObject1;
ValueObject2 = valueObject2;
}
private MyClass(){}
}
public class ValueObject
{
public string Value {get;}
public ValueObject(string value)
{
Value = value;
}
private ValueObject(){}
}
Run Code Online (Sandbox Code Playgroud)
我希望能够使用 EntityFramework Core 2.2.6 基于此模型创建数据库。
显然,EF Core 2.2.6 可以通过它们的参数化构造函数自动为这些类提供属性值,只要构造函数参数和类属性具有相同的名称(不区分大小写)。伟大的。
现在我希望 ValueObjects 与 MyClass 存储在同一个表中。要做到这一点,有人告诉我,我应该用modelBuilder.OwnsOne<>在OnModelCreating对的DbContext的,而不是modelBuilder.Property<>
中的 DBContext 配置 …
c# entity domain-driven-design value-objects entity-framework-core
value-objects ×10
c# ×4
entity ×3
complextype ×1
domain-model ×1
dto ×1
equals ×1
nhibernate ×1
null ×1