One to One error in Entity Framework 4
I have already read Entity Framework One-To-One Mapping Issues and this is not duplicate as the business rule specs are different here.
There are two tables, Invoices and Orders.
Invoices
-> InvoiceID (Primary, Auto Number)
Orders开发者_C百科
-> OrderID (Primary, Auto Number)
-> InvoiceID (FK InvoiceID of Invoices Table)
Now the problem is, EF requires One to Many relationship for this association if names of properties are not same. If names of properties are same then it serves purpose of derived class, but here Order is not derived class or Invoice.
InvoiceID(s) are generated for every shopping cart, but OrderID(s) are only generated for paid invoices, so Every Order has InvoiceID but every Order does not have corresponding Invoice.
If I create a seperate table for this, then I have to write too much code to do it. Is there any way I can remove this restriction and let EF still process my model.
However, currently if I change the model as follow, it works
Invoices
-> InvoiceID (Primary, Auto Number)
Orders
-> OrderID (Auto Number)
-> InvoiceID (Primary, FK InvoiceID of Invoices Table)
But is this good practice? Because by definition InvoiceID of Orders table will certainly be unique, but we will be referring everywhere OrderID for comparison and lot of other references. I know I can index the property, but I dont feel this design is perfect.
What seems to be the obvious solution here is to change the 1:* association between Invoice
and Order in the EDM into a 1:1 association. However, as you experienced, the mapping will not
validate when you have a Foreign Key Association between the two entities as in your model.
The only way to map a unique foreign key association is by using an Independent Association. This is the same type of association that we had in EF3.5, where foreign keys were not supported.
To turn the foreign key association into an independent association would mean removing the InvoiceID foreign key from the Order entity and recreating the association through mappings.
To make the change to the association, you’ll need to do the following:
- Delete the InvoiceID foreign key property from Order entity.
- Select the Asscoation between Invoice and Order.
- In the Properties window for the association, open the Referential Constraints by clicking the ellipses next to that property.
- Delete the constraint by clicking the Delete button.
- Right-click the association in the Designer and select Table Mapping from the context menu.
- In the Mapping Details window, click the element to expose the drop-down.
- From the drop-down, select Order. The mappings should populate automatically.
- Return to the Properties window for the association.
- For the property called “End2 Multiplicity,” which currently has the value * Collection of Orders, change that property to 1 (One of Order) using its drop-down list.
- Validate the model by right-clicking the design surface and choosing Validate. You will see that the error message related to this mapping is gone.
When encountering this problem in your application, you’ll have to decide which is more important to your model and your application logic: the foreign key scalar (e.g., Order.InvoiceID) or being able to define a 1:1 association between one entity (Invoice) and another (Order) when they are joined through a foreign key (InvoiceID).
The good news is that the new EF4.0 Lazy Loading will be still working with Independent Associations, just the Foreign key is not exposed. To get that you would have to go over to the navigation property (Invoice) and read its InvoiceID like the code below:
Order order = context.Orders.First();
int invoiceID = order.Invoice.InvoiceID;
Or you can use the code below to read it right on the Order entity withought having to Lazy Load or Eager Load the Invoice property:
int invoiceID = order.InvoiceReference.EntityKey.EntityKeyValues[0].Value;
精彩评论