2011-04-28 10 views
0

私はエンティティフレームワーク4、WCFおよびSilverlightを使用しています。既存の子を持つ新しいオブジェクトを追加すると複製されます

私は商品に対する注文の多面的な関係があります。

[Order]*--*[Product] 

最初にモデルを使用すると、Entity Frameworkによって自動的に結合テーブルが作成されます。サーバー側ですべてを作成すると、問題は解決します。この問題は、Silverlightを使用するときに発生します。

商品のリストを戻して画面に表示します。ユーザは新しい注文を作成し、注文の一部でなければならない商品を選択する。その後、WCFに提出されます。サーバー側では

var order = new order(); 
order.CustomerName = customerTextBox.Text; 
... 
order.Products = new ObservableCollection<Product>(); 

foreach (var product in selectedProducts) 
{ 
    order.Products.Add(product); 
} 
var proxy = new OrderService(); 
proxy.CreateOrderAsync(order); 

、それはしかし、奇妙な何かが起こるだけの非常にシンプルなaddメソッド

var db = new Model1Container(); 
db.Products.AddObject(order); 
db.SaveChanges(); 

です。これが保存されると、データベース内のほとんどすべてが数回複製されます。私の推測は、Entity Frameworkが循環リンクを数回通過しているためです。

db.Categories.Attatch(order)に変更しようとしました。しかし、これは何も救われませんでした。 注文を保存する前に、それぞれの製品をループして手動で接続しようとしました。しかし、これは例外がスローされ、オブジェクトがすでにコンテキストにアタッチされていることを示します。


編集:はこれを行う製品が複製されて停止します。しかし、テーブルのすべての注文は依然として複製されています。まだすべての関係を横断している必要がありますか?

db.Orders.AddObject(order); 
db.ObjectStateManager.ChangeObjectState(order, EntityState.Added); 

foreach (var product in order.Products) 
{ 
    db.ObjectStateManager.ChangeObjectState(product, EntityState.Unchanged); 
} 

db.SaveChanges(); 

答えて

1

代わりにこれを試してみてください:

var db = new Model1Container(); 
db.Categories.Attach(order); 
db.ObjectStateManager.ChangeObjectState(order, EntityState.Added); 
db.SaveChanges(); 

問題は、AddObject挿入オブジェクトグラフ内のすべての人跡未踏のエンティティ。 EFを使用する場合は、EFに何が変更されたかを明示的に伝える必要があります。ユーザーが注文を変更できるようにすると、まだhave problemsになります。

+0

何も影響しませんでした。 OrderテーブルとProductテーブルのすべてがまだ複製されています –

+0

私はあなたが提案したものを取り出し、それを少し拡張しました。今や製品は複製されませんが、テーブル内のすべての注文は依然として複製されます。 db.Orders.AddObject(order); db.ObjectStateManager.ChangeObjectState(order、EntityState.Added); foreach(順番に並んでいる製品。) { db.ObjectStateManager.ChangeObjectState(product、EntityState.Unchanged); } db.SaveChanges(); –

+0

すべての注文をどういう意味ですか?あなたは単一の注文を挿入していますか? –

0

WCF RIAを使用していますか?そうでない場合は、それを考慮する必要があります。 DomainServicesは多くの苦痛をかける。

また、 'order_position'テーブルを作成しないでください。このように、あなたは多種の関係をもう持たない。 1つのorder_positionには1つのオーダーと1つのプロダクトしかありません。また、価格を割り当てることもできます。これにより、統計で使用するために保存されます(商品Aのどれくらいのお金を見たいのですが、データベースの価格を数回変更した場合はどうなりますか?)。

+0

私は他のすべてのシナリオでRIAを使用しています。この場合、私はそれを使用する必要があります。また、Entity Frameworkはすでに実際には多対多の関係ではないように、表の下に結合表を作成します。そして、はい、私は結合テーブルに数量などを持たないという制限を知っています。わかりやすくするためテーブルを製品/注文に変更しました。 –

+0

OK。とにかくorder_positionテーブルを使用する理由は、そのような問題は本当に簡単になり、プログラムはスケーラビリティを保ちます。次のようにします。 Context = new Model1DomainContext(); 注文=新しい注文(); Context.orders.Add(order); ... foreachの(製品のVAR製品) {product.Order =オーダー。 Context.products.Add(order); } var submitOperation = Context.SubmitChanges(); submitOperation.Completed + = ... – LueTm

+0

これは、人々にそれが* *彼らにEntity Frameworkのでそれを行うための簡単な方法を示す前に、行うことができるような方法を実証するために、一度たとえばオフ、実際には非常に具体的です。 –