实体框架 – Code First Entity Framework模型中的一对多 – 关系如何工作?

给定标准的Northwind数据库(简化为简洁):

   [Table("Order Details")]
    public class OrderDetail : IValidatableObject
    {
        [Key, Column(Order = 1)]
        public int OrderID { get; set; }
        [Key, Column(Order = 2)]
        public int ProductID { get; set; }
        ...
    }
   [Table("Orders")]
    public class Order
        {
        public int OrderID { get; set; }
        ...
        public virtual ICollection<OrderDetail> OrderDetails { get; set; }
    }

我想知道它是如何工作的.我猜测,因为Order(OrderID)中的主键在OrderDetails(OrderID)中具有相同的外键,EF的规则正确地猜测它们具有外键/主键关系.

那是对的吗?

第二部分是另一个问题:

我有一个现有的数据库,其中外键的名称不相同(例如,将OrderDetail中的OrderId更改为RecordNumber – (我无法更改数据库)).在这种情况下,我正在努力了解如何关联这两个表.

我正在使用Fluent API(而不是上面的注释)并且具有以下内容:

---OrderDetails

// set up the primary key
HasKey(t => new { t.RecordNumber, t.ProductID };

---Order

HasKey(t => t.OrderId);

HasRequired(t => t.OrderDetails).WithMany().HasForeignKey(t => t.OrderId)

(最后一个语句看起来非常错误,因为HasForeignKey(…)似乎唯一能够与之相关的是声明的主复合键)

我也试过了

HasMany((t => t.OrderDetails).WithMany()

这似乎与先前的陈述不同,因为它可以没有OrderDetails.

两者都不起作用.

我试图表达的想法是订单必须至少有一个OrderDetails – 我正试图能够这样导航:

   Con.Orders.Single(o => o.OrderId == 1).OrderDetails

我遇到的问题是我用HasForeignKey(…)声明的外键与Orders上的任何内容都没有关系(并且代码抛出了一个适当的异常 – “Multiplicity无效”),我不知道如何实现我的目标.

有什么想法吗?我提前感谢您的帮助.

最佳答案

I’m guessing that because the primary key in Order (OrderID) has
foreign key in OrderDetails (OrderID) that is named the same, EF’s
rules correctly guess that they have a foreign-key/primary key
relationship.

是,对的.但重要的是,Order有OrderDetails的导航集合. EF从这个属性推断(以及OrderDetail中没有相应的导航属性,引用Order)这两个实体之间存在一对多的关系.然后,外键属性受命名约定的影响.

The idea I am trying to express is that an order must have at least
one OrderDetails.

您无法在模型和数据库之间的映射中定义此类约束.您必须在应用程序的业务逻辑中确保这一点.在一对多关系中,集合可以具有零元素.

使用Fluent API的正确映射是:

modelBuilder.Entity<Order>()
    .HasMany(order => order.OrderDetails)
    .WithRequired()
    .HasForeignKey(orderDetail => orderDetail.RecordNumber);
点赞