0

私は Entity Framework で遊んでいて、多対多のマッピングに関してつまずきにぶつかっています。Orders と Products という 2 つのエンティティがあるとします。

Order エンティティ内には次のものがあります。

int OrderID,
double OrderPrice
datetime OrderDate
ICollection<Product> Products
datetime DispactDate

等々...

次に、製品クラス内に

int ProductID
string ProductName
string ProductDescription

等々。

私のCode First EF DBには、注文にうまく対応するOrder Table、注文できる製品のリストを含むproductsテーブルがあり、次にEF Code-first migrationsを使用してEFが作成したOrderProductsの両方の主キーへの外部キー他のテーブル。すべて良い。

ただし、製品コレクションに複数の製品がある注文を保存しようとすると、EF は製品テーブルのすべてのエントリを複製しています。したがって、製品 10、12、および 13 を追加すると、元の ID ではなく、3 つの新しい ID を持つ 3 つの新しい行が作成され、それらにマッピングされます。次に、別の 20 個の既存の製品で別の注文を処理すると、製品テーブルに 20 個の新しいエントリが作成されます!

私の DBContext では、onModelCreatingEvent をオーバーライドしました。

modelBuilder.Entity<Order>()
                .HasMany(x=>x.Products)
                .WithMany()
                .Map(be =>
                    {
                        be.ToTable("OrderProducts");
                });

ここで何かが間違って設定されていると思います。これは、Entity Framework CTP5 で多対多の関係をマップする方法から取得しましたか?

以前は、注文用と製品用の 2 つの別々のリポジトリがありました。これらを Orders と Products の両方を公開する orderRepository にマージして、製品を orderRepository コンテキストにアタッチできるようにしました。製品を生成するために、コントローラ アクション AddProducts があります。

public RedirectToRouteResult Products(FormCollection selectedProducts)
        {
                currentOrder.Products = new List<Product>();
                foreach (string thisProduct in selectedProducts)
                {
                    int thisProductID = int.Parse(thisProduct);
                    Product selectedProduct = orderRepository.Products.Where(e => e.ProductID == thisProductID).FirstOrDefault();

                    if (selectedProduct != null)
                    {
                        orderRepository.AttachToContext(selectedProduct);
                        currentOrder.Products.Add(selectedProduct);
                    }                    
                }

                orderRepository.saveChanges(currentOrder);

}

4

3 に答える 3

1

orderRepositoryあなたの には とは異なるコンテキスト インスタンスがあると思われますProductsRepo。最初に製品をinのコンテキストにアタッチする必要があります。ProductsorderRepository

ところで、これは、エンティティごとのリポジトリが実際に邪魔になる理由の例です。リポジトリ パターンを使用する場合は、集約ルートで考える方がよい場合がよくあります。

于 2012-08-03T21:09:10.060 に答える
0

コンテキストを作成し、製品を取得し、注文を作成し、取得した製品を注文に追加するだけの小さな単体テストを作成できますか?

それは絶対にうまくいくはずです。既存のものを使用するのではなく、新しい製品オブジェクトを作成しているようです。または、作成して適切なエンティティ キーを設定していません。

通常、別のコンテキストに既にアタッチされているという警告が表示されるため、別のコンテキストから取得しているようには聞こえません。

于 2012-08-04T07:46:14.830 に答える
0

ありがとう。これを解決することができました。私の場合、それぞれにステータスOrderRepositoryを手動でマークする必要がありました。だから、私は今やっています:ProductEntitySate.UnchangedSaveOrder()

foreach (Product product in Orders.Products)
{
  context.Entry(product).State = System.Data.EntityState.Unchanged;
}

これは正常に機能していますが、注文内の各製品に有効な (および既存の) productid が既に割り当てられているのに、なぜこの手順を実行しなければならなかったのか知りたいです。変。

于 2012-08-08T07:59:16.173 に答える