繁体   English   中英

EF Core:域中没有导航属性的一对多关系

[英]EF Core: One to many relationship without navigation property in domain

嗨,互联网的好人:)
我正在尝试将 EF Core 5 实体用作 DDD 意义上的域实体。

我有两个实体的案例,每个实体都有自己的身份(意味着它们是 DDD 对象的实体类型,而不是 ValueObjects):国家和货币。

货币可以属于多个国家(例如欧元)。 另一方面,国家/地区只能有一种“当前有效”的货币,这不一定是始终相同的货币(例如,欧盟国家/地区放弃自己的本国货币以换取欧元)。

在特定的域有界上下文中,我只需要:

public class Country : Entity<Guid>
{
    public string Name { get; private set; }
    // the rest is omitted for readability
    public Currency Currency { get; private set; }
}

public class Currency : Entity<Guid>
{
    public string Name { get; set; }
    public string Code { get; set; }
}

我不想拥有导航属性: public ICollection<Country> Countries { get; private set; } public ICollection<Country> Countries { get; private set; } public ICollection<Country> Countries { get; private set; }对货币的实体,只是为了能够定义1:N的关系,因为这只会污染我的域名。

我试图将导航属性添加为 EF 阴影属性,但 EF 不允许它,抛出异常:

导航“国家/地区”无法添加到实体类型“货币”,因为基础类型上没有对应的 CLR 属性,并且无法在阴影状态下添加导航属性。

国家不能拥有货币(在 EF 意义上为 OwnsOne),因为这意味着货币必须在数据库中具有复合 {Id, IdCountry} PK,这将违反能够分配一种货币的要求到多个国家。

是否有解决方案可以在货币和国家/地区(或其他方式)之间建立关系,该关系不会使用导航属性污染域并允许将相同的 CLR 对象用作域和 EF 实体?

我正在尝试将 EF Core 5 实体用作 DDD 意义上的域实体。

EF 实体代表所谓的数据模型,它通常与域/业务模型不同,有自己的需求/建模规则,与其他模型不同,导航属性是很好的关系表示,允许生成不同类型的查询而无需使用手动连接等。

因此,通常您应该使用单独的模型并在需要时在两者之间进行映射,从而不会“污染”您的域模式或违反其规则。 就像您遵循域模型规则一样,您应该遵循数据模型规则 - 我不明白为什么人们认为 EF 应该遵循他们的规则而不是遵循 EF 规则。


无论如何,话虽如此,虽然非常有用,但 EF Core 导航属性不是强制性的(除了目前通过隐式连接实体和跳过导航的多对多) - 您可以同时拥有两者,只是主体,只是依赖或什至都没有结束.

您所需要的只是定义与正确的Has / With对的关系。 正确意味着在存在时使用传递导航属性,并在不存在时省略它。

在这种情况下,你可以使用这样的东西:

modelBuilder.Entity<Country>()
    .HasOne(e => e.Currency) // reference navigation property
    .WithMany() // no collection navigation property
    .IsRequired(); // omit this for optional relationship (to allow null FK)

如果从另一端开始配置,也可以达到同样的效果。 在这种情况下,您必须明确提供泛型类型参数,因为它无法自动推断:

modelBuilder.Entity<Currency>()
    .HasMany<Country>() // no collection navigation property
    .HasOne(e => e.Currency) // reference navigation property
    .IsRequired(); // omit this for optional relationship (to allow null FK)

您可以使用任何一种方式,只是不要同时使用两者,因为它是同一个关系,因此应该只配置一次以避免配置冲突(如果使用单独的IEnityTypeConfiguration<TEntity>类并不真正适合关系很好 - 一种关系有两端)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM