一对多的代码第一实体框架模型 - 关系如何工作? [英] One to Many in Code First Entity Framework model - How do the relationships work?

查看:129
本文介绍了一对多的代码第一实体框架模型 - 关系如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  [表(订单明细)] 
public class OrderDetail:IValidatableObject
{
[Key,Column(Order = 1)]
public int OrderID {get;组; }
[Key,Column(Order = 2)]
public int ProductID {get;组;
...
}
[表(订单)]
public class Order
{
public int OrderID {get;组; }
...
public virtual ICollection< OrderDetail> OrderDetails {get;组; }
}

我想知道如何正确运作。我猜,因为Order(OrderID)中的主键在OrderDetails(OrderID)中具有外键,命名相同,所以EF的规则正确地猜到它们具有外键/主键关系。



这是否正确?



第二部分是另一个问题:



有一个现有的数据库,其中外键不是命名相同的(将OrderDetail中的OrderId更改为RecordNumber,例如 - (我不能更改数据库))。在这种情况下,我正在努力想知道如何关联这两个表。



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

  --- OrderDetails 

//设置主键
HasKey(t => new {t.RecordNumber,t.ProductID} ;

---订单

HasKey(t => t.OrderId);

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

(最后一句话似乎令人难以置信错误的是,HasForeignKey(...)似乎只能与之相关联的是声明的主要复合键)



我也尝试过



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

这似乎与以前的语句不同,因为它可以没有OrderDetails。



这两个都不行。



我想表达的想法是,一个订单必须至少有一个OrderDetails - 而且我正在尝试g能够如此导航:

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

我遇到的问题是我宣布的外键HasForeignKey(...)与Orders无关(代码抛出适当的异常 - 多重性无效),我不知道如何完成我的目标。



任何想法?我很感激你的帮助。

解决方案


我猜,因为订单中的主键(OrderID)在OrderDetails(OrderID)中具有
外键,名称相同,EF的
规则正确地猜测他们有一个外键/主键
关系。


是的,正确。重要的是,订单有一个导航集合到 OrderDetail s。 EF从这个属性推断(事实上,在 OrderDetail 中没有相应的导航属性引用订单)那里是两个实体之间的一对多关系。然后外键属性受命名约定的限制。


我想表达的想法是,订单必须至少有
一个OrderDetails。


您不能在模型和数据库之间的映射中定义这样的约束。您必须确保在应用程序的业务逻辑中。在一对多关系中,集合可以有零个元素。



使用Fluent API的正确映射将是:

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


Given the standard Northwind database (reduced for conciseness):

   [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; }
    }

I'm wondering about how this works exactly. 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.

Is that correct?

Part two is another question:

I have an existing database where the foreign key is not named the same (change OrderId in OrderDetail to RecordNumber, for example - (I can't change the database)). In this case, I'm struggling trying to understand how to relate the two tables.

I'm using the Fluent API (and not the annotations as in above) and have something like this:

---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)

(The last statement seems incredibly wrong, in that the only thing that HasForeignKey(...) seems to be able to relate to is the declared primary composite key)

I've also tried

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

which would seem to be different from the prior statement in that it makes it possible to have no OrderDetails.

Neither works.

The idea I am trying to express is that an order must have at least one OrderDetails - and I'm trying to be able to navigate thusly:

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

The problem I am having is that the foreign key I declared with HasForeignKey(...) does not relates to anything on Orders (and the code throws an appropriate exception - "Multiplicity is not valid"), and I am left not knowing how to accomplish my goal.

Any thoughts? I appreciate your help in advance.

解决方案

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.

Yes, correct. The important part though is that Order has a navigation collection to OrderDetails. EF infers from this property (and the fact that there is no corresponding navigation property in OrderDetail refering to Order) that there is a one-to-many relationship between the two entities. Then the foreign key property is infered by naming conventions.

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

You can't define such a constraint in the mapping between model and database. You must ensure this in your application's business logic. In a one-to-many relationship the collection can have zero elements.

The correct mapping with Fluent API would be:

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

这篇关于一对多的代码第一实体框架模型 - 关系如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆