3

こんなモデルができたら…

public class Order
{
    [Key, Column(Order = 1)]
    public int CustomerId { get; set; }
    [Key, Column(Order = 2)]
    public int OrderId { get; set; }

    public ICollection<OrderItem> 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; }
}

...データベースにグラフを追加するときに、外部キーの値OrderItem.CustomerIdOrderItem.OrderId手動で提供する必要はありません。Order - OrderItems

var order = new Order
{
    CustomerId = 5,
    OrderId = 1,
    Items = new List<OrderItem>
    {
        // I don't need to set CustomerId and OrderId here
        new OrderItem { OrderItemId = 12 }
    }
};
context.Orders.Add(order);
context.SaveChanges();

SaveChangesOrderとを挿入する SQL ステートメントを生成しますOrderItem。それOrderItemは次のとおりです。

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

そのため、FKCustomerIdOrderIdは正しく設定されています (@0=5@1=1)。

ただし、Customerナビゲーション プロパティをモデルに追加するだけで、エンティティへの別の関係をモデルに追加するとOrder...

public Customer Customer { get; set; }

...Customerこのようなクラスで...

public class Customer
{
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int CustomerId { get; set; }
}

...そして、上記と同じコードを呼び出します ( DB にCustomerwith CustomerId=5が存在すると仮定して) 次の SQL を取得します。

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

ほぼ同じですがCustomerId0この場合 ( @0=0) は関係の外部キー制約違反になりOrder - OrderItemます。Customerwith CustomerId=0が存在し、この顧客がOrderwith OrderId=を持っていた場合1、例外は発生せずOrderItem、間違った注文に追加され、例外よりも悪い可能性があります。

CustomerIdこの問題は、 (FK の一部である) を new に設定することで修正できますOrderItem

Items = new List<OrderItem>
{
    // I don't need to set OrderId here, BUT CustomerId
    new OrderItem { CustomerId = 5, OrderItemId = 12 }
}

または - Id を持つ顧客をコンテキストに添付することで修正でき5ます (なぜそれが機能するのかわかりません)。

FK (またはこの例では FK の一部) を手動で提供しなければならない合理的な説明はありますか、それともバグですか?

(このモデルでは、EF 5.0 と .NET 4.0 を使用しました。)

4

1 に答える 1

0

あなたのモデルは私には奇妙に見えますが、それがあなたの混乱を引き起こしているのではないかと思います.

私が見たものに基づいて、多くの注文を持つことができる顧客がいて、各注文には各タイプの Or​​derItem を 1 つだけ持つ必要がありますが、多くの OrderItems を持つことができると推測しています。1 つの注文が複数の顧客に属することはできません。1 つの OrderItem が複数の Order に属することができます。

それが本当なら、次のようなモデルが必要だと思います。

public class Customer
    {
        //Is the key by naming convention or you could use [Key]
        public Guid CustomerId { get; set; }
        public ICollection<Order> Orders { get; set; } 
    }
    public class Order
    {
        //Is the key by naming convention or you could use [Key]     
        public Guid OrderId { get; set; }
        public Guid CustomerId { get; set; } //This doesn't need to be part of the key 
        public Customer Customer { get; set; }
        public ICollection<OrderItem> OrderItems { get; set; } 
    }
    public class OrderItem
    {
        [Key, Column(Order = 0)]
        public Guid OrderItemId { get; set; }
        [Key, Column(Order=1)]
        public Guid OrderId { get; set; }
        public ICollection<Order> Orders { get; set; }
    }

次に、OrderItems by Customer を知る必要があるかどうかを照会する必要がある場合は、Include または次のようなデータ プロジェクションを使用してそれを行うことができます。

OrderItems.Select(x=>new { 
CustomerId = x.Order.Customer.Id,
//this rest of your properties
});

または、エンティティ全体が必要な場合

  OrderItems.Include(x=>x.Order.Customer)
于 2013-02-20T01:58:49.523 に答える