The*_*ent 5 c# entity domain-driven-design value-objects entity-framework-core
考虑这些简单的类。它们属于具有领域驱动设计 (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 配置OnModelCreating看起来像这样:
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);
}));
Run Code Online (Sandbox Code Playgroud)
现在它似乎modelBuilder.OwnsOne<>并且modelBuilder.Property<>是相互排斥的,这意味着你不能同时使用它们,因为每次我尝试Add-Migration使用它们时我都会得到:
'ValueObject' cannot be used as a property on entity type 'MyClass' because it is configured as a navigation.
Run Code Online (Sandbox Code Playgroud)
但如果我不使用modelBuilder.Property<>而只使用modelBuilder.OwnsOne<>,我会得到:
找不到适合实体类型“MyClass”的构造函数。以下构造函数的参数无法绑定到实体类型的属性:无法绑定“MyClass(ValueObject valueObject1, ValueObject valueObject2)”中的“valueObject1”、“valueObject2”。
这意味着属性绑定模式的构造函数仅在我用于modelBuilder.Property<>配置MyClass.
所以我的问题是:我应该怎么配置的DbContext允许EF核心通过参数化的构造同时设置属性值,并在同一个表作为实体店ValueObjects?
所以这就是发生的事情。正如@Gert Arnold 指出的:
1. 您需要在域模型的所有属性上拥有私有设置器。从版本 2.2.6 开始,EF Core 无法使用只读属性。
但这不是我的问题。事实证明,我忘记了在我自己的项目中包含一个私有构造函数MyClass。我只是希望在我花费数小时的工作并弄清楚之前看到@Ivan Stoev 的评论。EF Core给我的错误信息太隐晦了,并没有指出问题所在:
找不到实体类型“MyClass”的合适构造函数。以下构造函数的参数无法绑定到实体类型的属性:无法绑定“MyClass(ValueObject valueObject1, ValueObject valueObject2)”中的“valueObject1”、“valueObject2”。
实际上,该特定构造函数没有问题。
2.如果您希望 EF Core 正确使用构造函数绑定并通过构造函数参数向属性提供值,则只需拥有一个私有的无参数构造函数即可。
不是这种情况。EF Core 根本无法使用构造函数绑定将实体注入到其他实体中。
它基本上告诉我们不能使用特定的构造函数,并且因为它根本找不到合适的构造函数来使用,通过提供无参数构造函数,您可以为它提供一种无需构造函数绑定即可创建对象的方法。
3. 您应该使用modelBuilder.OwnsOne<>而DbContext.OnModelCreating不是modelBuilder.Property<>为实体(在 DDD 中)配置值对象,以将其存储在与实体相同的数据库表中。
我认为 EF Core 需要向您提供更清晰的信息,说明当您没有私有、无参数的构造函数时,它应该使用哪个构造函数是如何令人困惑的。我将向 EF Core 团队提出这个问题。
| 归档时间: |
|
| 查看次数: |
1982 次 |
| 最近记录: |