EF DbContext/POCO エンティティを独立した方法で使用したい。つまり、ビジネス層からエンティティの階層を取得し、いくつかの変更を加えてから、階層全体をビジネス層に送り返し、データベースに永続化します。各 BLL 呼び出しは、DbContext の異なるインスタンスを使用します。これをテストするために、そのような環境をシミュレートするコードを書きました。
Customer
まず、関連するプラスを取得しますOrders
: OrderLines
-
Customer customer;
using (var context = new TestContext())
{
customer = context.Customers.Include("Orders.OrderLines").SingleOrDefault(o => o.Id == 1);
}
Order
次に、新しいものを 2 つ追加しOrderLines
ます :-
var newOrder = new Order { OrderDate = DateTime.Now, OrderDescription = "Test" };
newOrder.OrderLines.Add(new OrderLine { ProductName = "foo", Order = newOrder, OrderId = newOrder.Id });
newOrder.OrderLines.Add(new OrderLine { ProductName = "bar", Order = newOrder, OrderId = newOrder.Id });
customer.Orders.Add(newOrder);
newOrder.Customer = customer;
newOrder.CustomerId = customer.Id;
最後に、変更を永続化します (新しいコンテキストを使用):-
using (var context = new TestContext())
{
context.Customers.Attach(customer);
context.SaveChanges();
}
SaveChanges() を呼び出す前に、新しいエンティティの状態を変更する必要があることは間違いないため、この最後の部分は不完全であることに気付きました。顧客を追加または添付しますか? どのエンティティの状態を変更する必要がありますか?
この段階に到達する前に、上記のコードを実行すると例外がスローされます。
同じキーを持つオブジェクトが ObjectStateManager に既に存在します。
2 つのエンティティの ID を明示的に設定していないOrderLine
ことが原因のようで、どちらもデフォルトで 0 です。EF が自動的に処理するので、これで問題ないと思いました。私は何か間違ったことをしていますか?
また、この「切り離された」方法で作業すると、関係を設定するために多くの作業が必要になるようです。新しい注文エンティティをcustomer.Orders
コレクションに追加し、新しい注文のCustomer
プロパティとそのCustomerId
プロパティを設定する必要があります。これは正しいアプローチですか、それとももっと簡単な方法がありますか?
自己追跡エンティティを見たほうがよいでしょうか? それらが廃止されているか、少なくともPOCOを支持して落胆していることをどこかで読んだことがあります。