EntityFramework Relationship which way round

本文关键字:round way which Relationship EntityFramework | 更新日期: 2023-09-27 18:29:03

如果我有一个客户进行查询(只允许一次查询),我有:

public class Customer
{
    public string Name {get;set;}
    public string ContactNumber {get;set;}
    public virtual Inquiry Inquiry {get;set;}
}
public class Inquiry
{
    public string Product {get;set;}
    public string Information {get;set;}
    public string Reason {get;set;}
}

还是我有这样的:

public class Customer
{
    public string Name {get;set;}
    public string ContactNumber {get;set;}
}
public class Inquiry
{
    public string Product {get;set;}
    public string Information {get;set;}
    public string Reason {get;set;}
    public virtual Contact Contact {get;set;}
}

在第一个场景中,我确信如果Inquiry被删除,Customer也会被删除,除非我使用public Guid? InquiryId {get;set;}和导航属性。这种情况确实更有意义。

在第二个场景中,我非常确信如果Customer被删除,Inquiry将被删除,这是所需的效果。但是,它确实使导航属性有点多余,因为您希望查看"客户查询"生成了什么customer => inquiry,而不是"客户询问"生成了哪些inquiry.FirstOrDefault(x => x.Customer.Id.Equals(customerId))

在某种程度上,Delete On Cascade属性有帮助,但导航属性是多余的,但在另一方面,Delete On Cascade没有帮助(需要更多的代码才能使其正常工作),但导航特性有帮助。

那么,你如何决定该走哪条路呢?

认为第一种情况的另一个缺点是,您必须手动删除相关的Inquiry,因为当您删除Customer时,它只会忽略级联(因为它在代码中已关闭)。

EntityFramework Relationship which way round

将您的问题和评论中的以下信息放在一起。。。

  • 客户只有一个查询
  • 这样做的效果是,当客户被删除时,相关的查询也应该被删除
  • 您希望客户和查询之间的关系是一对一或零

如果没有进一步的映射规范,这两个模型都不能满足这些要求。然而,您可以通过使用第一个模型并使用Fluent API添加显式映射:来实现目标

modelBuilder.Entity<Customer>()
    .HasOptional(c => c.Inquiry)
    .WithRequired()
    .WillCascadeOnDelete(true);

相关的CustomerInquiry将共享相同的主键值,即Inquiry中的主键是Customer的外键。

关于一些错误假设的几点评论:

在第一种情况下,我很确定如果查询被删除客户也将被删除。

这是不正确的,因为您的模型中没有外键属性,在这种情况下,EF将采用可选关系,并且默认情况下不启用级联删除。

在第二个场景中,我非常确定如果一个客户删除了查询将被删除。

由于同样的原因而不正确。

这是一种一对一或零(关系)。

您的第一个和第二个场景都表示一对多关系,因为如果您只在关系的一侧具有导航属性,则这是EF将假设的默认关系。如果你在另一边公开一个收藏,或者不让它成为一对多的关系,这都无关紧要。例如,在第一个场景中,您可能有两个客户引用同一个查询,这意味着(从概念上和数据库的角度来看)该查询将有两个(=许多)客户。