【问题标题】:Table Splitting - Migration Warning表拆分 - 迁移警告
【发布时间】:2022-01-12 14:42:12
【问题描述】:

我的场景:

我有一个产品,它具有在产品实体中声明的各种属性,例如价格、尺寸等。

此外,Product 可以具有 StockRequirements 的集合,即当使用该产品时,StockRequirement 可以耗尽组成 StockItems相应的数量。

在一个用例下,我只想要产品,以便我可以使用核心属性。对于另一个用例,我想要具有 StockRequirements 的产品。

这意味着在检索产品时,我可能会在不同的上下文中使用它。我选择的方法是使用 EF 表拆分。

我有一个 Products 存储库和一个 ProductStockRequirements 存储库。它们指的是同一个独特的产品。

产品存储库将提供仅包含核心详细信息的产品实体。

ProductStockRequirements 存储库将提供 ProductStockRequirements 实体,该实体没有核心详细信息,但有 StockRequirements 列表。

这似乎是一种合理的方法,因此当我只想更改产品的价格时,我不会检索“拥有”的 StockRequirements。同样,如果我只对使用 StockRequirements 感兴趣,那么我不会检索其他核心细节。

实体

class Product
{
    public int Id { get; set; }
    public string CoreProperty { get; set; }
}

class ProductStockRequirements
{
    public int Id { get; set; }
    public List<StockRequirement> StockRequirements { get; set; }
}

产品映射

b.ToTable("Products");
b.HasKey(p => p.Id);
b.Property(p => p.CoreProperty).IsRequired();

ProductStockRequirementsMapping

b.ToTable("Products");
b.HasKey(p => p.Id);

b.OwnsMany<StockRequirement>(p => StockRequirements, b =>
{
    b.ToTable("StockRequirements");
    b.WithOwner().HasForeignKey("ProductId");
}

b.HasOne<Product>()
    .WithOne()
    .HasForeignKey<ProductStockRequirements>("Id");

运行迁移时,我收到警告:

实体类型“ProductStockRequirements”是可选的依赖项 使用没有任何必需的非共享属性的表共享 可用于识别实体是否存在。如果都可以为空 属性在数据库中包含一个空值,然后是一个对象实例 不会在查询中创建。添加创建所需的属性 其他属性为空值的实例或标记传入的实例 根据需要导航以始终创建实例。

专注于建议:

根据需要标记传入导航以始终创建实例

我试过了:

b.HasOne<Product>()
    .WithOne()
    .HasForeignKey<ProductStockRequirements>("Id")
    .IsRequired();

b.HasOne<Product>()
    .WithOne()
    .IsRequired()
    .HasForeignKey<ProductStockRequirements>("Id");

无济于事。

警告似乎不会导致任何不良行为。我所有的测试都通过了。但是,似乎我应该能够创建一个删除此警告的地图,但找不到路。

【问题讨论】:

    标签: entity-framework-core


    【解决方案1】:

    这应该只是

    class Product
    {
        public int Id { get; set; }
        public string CoreProperty { get; set; }
        public List<StockRequirement> StockRequirements { get; set; } = new List<StockRequirement>();
    }
    

    由于 StockRequiremens 不是 Product 实体的一部分,除非您请求,否则不会加载 related data

    实体模型根本不是定义聚合的正确层。聚合是通过从实体模型中选择单个实体以及 0 个相关实体来定义的。通常,您将密切相关和弱实体一起包含在一个聚合中。

    如果您的实体模型是 23 个相关实体的图,您可以将其组织成 10 个独立且部分重叠的聚合或子图。

    【讨论】:

    • 谢谢,大卫。我确实可以在产品存储库上使用 2 种方法。一种支持属性更新用例,一种支持库存管理用例。但是,我仍然有相同聚合中的 2 个用例的逻辑。我的动机是使用两个单独的聚合,专注于它们各自的用例,但对聚合实体使用同一个表。似乎分表是应对这一挑战的完美答案。我还可以让 StockRequirements 在第二个聚合上“拥有”,而不必“包含”它们。我是否让事情变得不必要地复杂化了?
    • StockRequirement 等弱实体没有自己的 Aggregate。
    • 不确定我是否遵循,或者我不清楚。这两个聚合是ProductProductStockRequirements。然后ProductStockRequirements 拥有StockRequirement 的集合,其中包含数量和指向基础股票项目的指针。 StockRequirement 永远不会被视为聚合。
    • 我明白了。我只是不同意这是一个有用的设计。
    • 谢谢你,更多。 “而实体模型根本不是定义聚合的正确层。”您是否建议我试图使我的实体模型隐式支持不同的用例,而不是用例聚合明确决定如何为用例目的检索实体(和相关实体)?
    猜你喜欢
    • 2020-11-11
    • 1970-01-01
    • 2019-08-12
    • 2020-10-27
    • 2020-01-29
    • 1970-01-01
    • 2019-07-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多