gpt4 book ai didi

c# - EF Core 和 DDD : Store ValueObjects in the same table as Entities, 也使用参数化构造函数来设置实体的属性值

转载 作者:太空宇宙 更新时间:2023-11-03 12:00:00 25 4
gpt4 key购买 nike

考虑这些简单的类。它们属于具有领域驱动设计 (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(){}
}

我希望能够使用 EntityFramework Core 2.2.6 基于此模型创建数据库。

显然,EF Core 2.2.6 可以通过它们的参数化构造函数自动为这些类提供属性值,只要构造函数参数和类属性具有相同的名称(不区分大小写)。太好了。

现在我希望将 ValueObject 存储在与 MyClass 相同的表中。有人告诉我,要做到这一点,我应该使用 modelBuilder.OwnsOne<>OnModelCreating的 DBContext,而不是 modelBuilder.Property<>

OnModelCreating中的DBContext配置看起来像这样:

modelBuilder.Entity<MyClass>(b => b.HasKey(mc => mc.Id));
modelBuilder.Entity<MyClass>(b => b.OwnsOne(mc => mc.ValueObject1,rb =>
{
rb.Property(vo => vo.Value);
}));
modelBuilder.Entity<MyClass>(b => b.OwnsOne(mc => mc.ValueObject2, rb =>
{
rb.Property(vo => vo.Value);
}));

现在看来modelBuilder.OwnsOne<>modelBuilder.Property<>是互斥的,这意味着你不能同时使用它们,因为每次我尝试 Add-Migration有了他们两个,我得到:

'ValueObject' cannot be used as a property on entity type 'MyClass' because it is configured as a navigation.

但如果我不使用 modelBuilder.Property<>并且只使用 modelBuilder.OwnsOne<> ,我得到:

No suitable constructor found for entity type 'MyClass'. The following constructors had parameters that could not be bound to properties of the entity type: cannot bind 'valueObject1', 'valueObject2' in 'MyClass(ValueObject valueObject1, ValueObject valueObject2)'.

这意味着属性绑定(bind)模式的构造函数只有在我使用 modelBuilder.Property<> 时才有效在 MyClass 上配置属性.

所以我的问题是:我应该如何配置 DBContext 以允许 EF Core 通过参数化构造函数设置属性值,将 ValueObject 存储在与实体相同的表中?

最佳答案

这就是发生的事情。正如@Gert Arnold 指出的那样:

<强>1。您需要在域模型的所有属性上都有私有(private) setter 。从版本 2.2.6 开始,EF Core 无法使用只读属性。

但这不是我的问题。结果我忘了在相当于 MyClass 的地方包含一个私有(private)构造函数在我自己的项目中。我只是希望在我花费数小时的工作并弄明白之前看到@Ivan Stoev 的评论。 EF Core给我的错误信息太隐晦了,没有指出问题:

No suitable constructor found for entity type 'MyClass'. The following constructors had parameters that could not be bound to properties of the entity type: cannot bind 'valueObject1', 'valueObject2' in 'MyClass(ValueObject valueObject1, ValueObject valueObject2)'.

在现实中,那个特定的构造函数没有问题。

<强>2。 如果您希望 EF Core 正确使用构造函数绑定(bind)并通过构造函数参数将值提供给您的属性,您只需拥有一个私有(private)的、无参数的构造函数。不是这种情况。 EF Core 根本无法使用构造函数绑定(bind)将实体注入(inject)其他实体。它基本上是在告诉我们不能使用特定的构造函数,并且因为它根本找不到合适的构造函数来使用,所以通过提供无参数构造函数,你给了它一种创建对象的方法 构造函数绑定(bind)

<强>3。你应该使用 modelBuilder.OwnsOne<>在你的DbContext.OnModelCreating而不是 modelBuilder.Property<>为实体(在 DDD 中)配置值对象以存储在与实体相同的数据库表中。

我认为 EF Core 需要给你一个更清晰的信息,告诉你当你没有私有(private)的、无参数的构造函数时,它是如何混淆它应该使用哪个构造函数的。 I'll bring it up with the EF Core team .

关于c# - EF Core 和 DDD : Store ValueObjects in the same table as Entities, 也使用参数化构造函数来设置实体的属性值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57467063/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com