【问题标题】:Multiple optional one-to-one relations where one (any) of them is required多个可选的一对一关系,其中一个(任何)是必需的
【发布时间】:2017-12-02 02:57:04
【问题描述】:

我检查了this one 和其他相关问题,但找不到适合我的案例的有效解决方案。

所以,我有 3 个实体,PrintingMethodPrintingSubMethodPrintPricing。规则是:

  • PrintingMethod 有一个 PrintingSubMethod 的集合。 >> 没问题。
  • PrintingMethod 可以有零个或一个PrintPricing
  • 每个PrintingSubMethod必须有一个PrintPricing
  • 每个PrintPricing必须PrintingMethodPrintingSubMethod链接。

这是前两个实体:

Public Class PrintingMethod
    Public Property Id As Integer
    Public Property Name As String
    Public Property SupportsAdditionalColors As Boolean

    Public Overridable Property SubMethods As ICollection(Of PrintingSubMethod)
    Public Overridable Property AdditionalColorPricing As PrintPricing
End Class


Public Class PrintingSubMethod
    Public Property Id As Integer
    Public Property Name As String

    Public Property PrintingMethodId As Integer

    <ForeignKey("PrintingMethodId")>
    Public Overridable Property ParentMethod As PrintingMethod

    Public Overridable Property Pricing As PrintPricing
End Class

这是第三个的插图:

Public Class PrintPricing
    Public Property Id As Integer

    <ForeignKey("LinkedSubMethod")>
    Public Property SubMethodId As Integer

    <ForeignKey("LinkedMethod")>
    Public Property MethodId As Integer

    Public Overridable Property LinkedSubMethod As PrintingMethodCode
    Public Overridable Property LinkedMethod As PrintingMethod
End Class

那么,这是否可以使用 DataAnnotations 或 Fluent API 来实现?如果不是,请随时提出替代方案。

注意事项:

  • 为简洁起见,删除了不相关的字段和 DataAnnotations。
  • 我使用的是 Entity Framework 6.0。
  • 虽然我的代码是用 VB 编写的,但也欢迎任何 C# 答案。

【问题讨论】:

    标签: c# .net vb.net entity-framework one-to-one


    【解决方案1】:

    如果我没看错你的问题,你的关系图应该是这样的:

    PrintingMethod       [1:n]  PrintingSubMethod
    PrintingMethod    [0..1:1]  PrintPricing   
    PrintingSubMethod [0..1:1]  PrintPricing
    

    值得注意的是,纯粹的一对一关系是不可能的,因为主体实体必须始终首先出现(不存在违反我们所追求的1:1 约束的依赖实体)。因此,1:1 在实践中往往是一对零或一的关系。

    每个PrintingSubMethod 必须有一个PrintPricing

    因此,执行此规则需要您在其他层进行处理。


    public class PrintPricing 
    {
        [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int Id { get; set; }
    
        // You may want to uncomment the "navigation" properties, 
        // but I'm going to leave it commented so you know this is
        // not required for it to establish the relationship correctly, 
        // because this class represents the principal end of the relationship
        // public virtual PrintingMethod Method { get; set; }
        // public virtual PrintingSubMethod SubMethod { get; set; }
    }
    
    public class PrintingMethod 
    {
        [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        [ForeignKey("Pricing")] // foreign keys go on the dependent ends for 0:1 relationships
        public int Id { get; set; }
        public virtual List<PrintingSubMethod> SubMethods { get; set; }
    
        public virtual PrintPricing Pricing { get; set; }
    }
    
    public class PrintingSubMethod
    {
        [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        [ForeignKey("Pricing")]
        public int Id { get; set; }
        public virtual PrintingMethod Method { get; set; }
    
        public virtual PrintPricing Pricing { get; set; }
    }
    

    如果您愿意,您也可以手动为PrintingMethod [1:n] PrintingSubMethod 关系定义外键,但 EF 足够聪明,可以自行计算,所以这是可选的。我个人更喜欢手动定义外键。

    【讨论】:

    • 您对图表是正确的,我在另一层执行该规则没有问题。仍然不确定如何实施您建议的解决方案。实际上,我是 EF 的新手,所以如果您详细说明如何实现这个最好在可能的情况下使用 DataAnnotations,那就太好了。谢谢。
    • 我关心的部分是如何为同一张表创建两个0-1关系。因为我知道使用 DataAnnotations 的方法是将目标表中的FK 也设为PK
    • @AhmedAbdelhameed 我添加了一些代码。关键是将外键添加到从属端,而不是主端。我还没有尝试运行它,所以请随时进行编辑:)
    • +1 非常感谢您的努力。好的,我在PrintingMethod 中尝试了您的代码与可空FK,并得到this model diagram (不知道为什么它说1-n!) 取消注释导航属性时也是如此,我得到this error
    • 另一方面,在看到您的解决方案之前,我使用了something,生成了this model diagram。它似乎有效,但我对此并不那么自信。如果您查看它并让我知道它是否有问题以及它是否是更好的方法如果可以,我将不胜感激。再次感谢:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-23
    • 2011-07-29
    • 1970-01-01
    • 1970-01-01
    • 2021-01-19
    相关资源
    最近更新 更多