Note that there are some explanatory texts on larger screens.

plurals
  1. POWhy do I have to supply foreign key property values manually (in this situation)?
    primarykey
    data
    text
    <p>When I have a model like this...</p> <pre><code>public class Order { [Key, Column(Order = 1)] public int CustomerId { get; set; } [Key, Column(Order = 2)] public int OrderId { get; set; } public ICollection&lt;OrderItem&gt; Items { get; set; } } public class OrderItem { [Key, Column(Order = 1)] public int CustomerId { get; set; } [Key, Column(Order = 2)] public int OrderId { get; set; } [Key, Column(Order = 3)] public int OrderItemId { get; set; } } </code></pre> <p>...I don't need to supply the foreign key values <code>OrderItem.CustomerId</code> and <code>OrderItem.OrderId</code> manually when I add an <code>Order - OrderItems</code> graph to the database:</p> <pre><code>var order = new Order { CustomerId = 5, OrderId = 1, Items = new List&lt;OrderItem&gt; { // I don't need to set CustomerId and OrderId here new OrderItem { OrderItemId = 12 } } }; context.Orders.Add(order); context.SaveChanges(); </code></pre> <p><code>SaveChanges</code> will generate SQL statements to insert the <code>Order</code> and the <code>OrderItem</code>. For <code>OrderItem</code> it is:</p> <pre><code>exec sp_executesql N'insert [dbo].[OrderItems]([CustomerId], [OrderId], [OrderItemId]) values (@0, @1, @2) ',N'@0 int,@1 int,@2 int',@0=5,@1=1,@2=12 </code></pre> <p>So, the FKs <code>CustomerId</code> and <code>OrderId</code> are correctly set (<code>@0=5</code> and <code>@1=1</code>).</p> <p>However, if I add another relationship to a <code>Customer</code> entity to the model by just adding a navigation property to <code>Order</code>...</p> <pre><code>public Customer Customer { get; set; } </code></pre> <p>...with a <code>Customer</code> class like this...</p> <pre><code>public class Customer { [DatabaseGenerated(DatabaseGeneratedOption.None)] public int CustomerId { get; set; } } </code></pre> <p>...and call the same code like above (assuming that a <code>Customer</code> with <code>CustomerId</code> = <code>5</code> exists in the DB) I get the following SQL:</p> <pre><code>exec sp_executesql N'insert [dbo].[OrderItems]([CustomerId], [OrderId], [OrderItemId]) values (@0, @1, @2) ',N'@0 int,@1 int,@2 int',@0=0,@1=1,@2=12 </code></pre> <p>Almost the same, but the <code>CustomerId</code> is <code>0</code> in this case (<code>@0=0</code>) which results in a foreign key constraint violation for the <code>Order - OrderItem</code> relationship. If a <code>Customer</code> with <code>CustomerId</code> = <code>0</code> would exist and this customer had an <code>Order</code> with <code>OrderId</code> = <code>1</code>, no exception would occur and the <code>OrderItem</code> would have been added to a wrong order which might be worse than an exception.</p> <p>The problem can be fixed by setting the <code>CustomerId</code> (which is part of the FK) in the new <code>OrderItem</code>:</p> <pre><code>Items = new List&lt;OrderItem&gt; { // I don't need to set OrderId here, BUT CustomerId new OrderItem { CustomerId = 5, OrderItemId = 12 } } </code></pre> <p>Or - it can be fixed by attaching the customer with Id <code>5</code> to the context (I have no clue why it works then).</p> <p><strong>Is there a reasonable explanation why I have to supply the FK (or part of the FK in this example) manually or is this a bug?</strong></p> <p>(I have used EF 5.0 with .NET 4.0 for this model.)</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload