4

エラーが発生しない場合(「すべて」)にのみ、データ(エンティティオブジェクト)をデータベースに入れる方法を実装しようとしています。エラーが発生した場合、データベースには何も作成されません (「または何も」)。私が「すべてか無か」と呼んでいるもの。

問題は、他のエンティティに依存するエンティティを作成する必要があることです。例を次に示します。

0) コンテキストを作成します

DBContext ctx = new DBContext();

1) Invoice エンティティ オブジェクトを作成し、コンテキストに追加します。

Invoice inv1 = new Invoice();
inv1 .Number = "Invoice-2546432";

if(!ctx.Invoice.Exists(i => i.Number == "Invoice-2546432")) // problem n°1
   ctx.AddObject(inv1 );
else 
   throws new Exception('blah blah');

2) 請求書には請求明細行があります。

InvoiceLine line = new InvoiceLine();
line .ID_INVOICE = in1.ID; // problem n°2
line .Label = "Line 1";
line .Ammount = 5.3;
ctx.AddObject(line );

3) 最後に:

ctx.SaveChanges();

したがって、すべてがうまくいった場合、次のようなものがあります。

   Table INVOICE
=====================
ID  |      NUMBER
_____________________
 0  |  Invoice-2454876
_____________________
 1  |  Invoice-2487432
_____________________
 2  |  Invoice-2546432


           Table INVOICE_LINE
=========================================
ID  |  ID_INVOICE  |   LABEL   |  AMOUNT 
_________________________________________
 0  |       0      |   Line 1  |   2.6    
_________________________________________
 1  |       0      |   Line 2  |   7.6    
_________________________________________
 2  |       1      |   Line 1  |   7.6    
_________________________________________
 3  |       2      |   Line 1  |   8.6    
_________________________________________

コメントで述べたように、2 つの問題があります。

問題 1:

存在テストは、新しいオブジェクトを追加したコンテキスト自体ではなく、データベースでのみチェックするため、常に false を返します。

問題 2:

請求書はコンテキストにのみ追加され、データベースにはまだ追加されていないため、請求書の将来の ID はありません。そのため、請求明細行に設定できません。

1)基本的に、データベースにデータを追加する安全な方法を知っていますか?私は金融アプリケーションを開発しており、データベースに挿入された破損したデータがないことを確認したいと考えています (例: 請求書明細行の挿入に失敗した場合、請求書全体をデータベースに挿入しないようにしたい)

2) そのようなことに関連するデザイン パターンは見つかりませんでした。ひょっとして、あなたはそれを知っていますか?

3)エンティティフレームワークでコンテキストオブジェクトをよく理解しているかどうかはわかりません:これが私の理解です:

コンテキストは (基本的に) データベースへの接続です。エンティティを追加すると、それはメモリのどこかに保存され、SaveChanges() を呼び出すとデータベースに挿入されます。これは正しいです ?ADO/entity フレームワークがどのように機能するかを詳しく説明している Web サイトまたは本を知っていますか?

4

2 に答える 2

6

あなたはまだsqlまたはrecord考え方で考えているようです-EFはORMであり、あなたが説明した低レベルのハウスキーピングの多くを行います。

Invoice理想的には、 と の間に1 対多の関係があることは明らかであるため、InvoiceLineこの 1 対 N の関係を EF でモデル化し、EF に ID 列の修正/割り当てを心配させる必要があります。

Invoice invoice = new Invoice();
invoice.InvoiceLines.Add(new InvoiceLine() { ... set fields here })
... add more details

// Now add just the invoice to the context. The lines will be added automatically
ctx.AddObject(invoice);
ctx.SaveChanges();

2 番目の質問に答えるためTransactionScope()に、単一の作業単位の下で複数のデータベース操作を集約するために使用することを検討できます。

最後の質問に答えるために-コンテキストをデータベース接続と考えるべきではありません-それによって管理されるエンティティの状態を管理するのは、より高いレベルの概念です。

またSaveChanges()、コンテキストへのすべての変更がトランザクションの下で永続化されるようにする必要があるため、単一のコンテキストを使用している場合は通常、追加のトランザクション制御は必要ありません。

ここここにあるこれらの SO 投稿は役に立ちますか?

于 2013-01-04T10:24:42.967 に答える
-1

2 番目の質問に答えるには、Status as bit のようなフィールドを請求書テーブルに追加します。すべての請求書明細が例外なく保存された場合、最終的に関連する請求書を更新し、Status = true に設定します。

TransactionScope を使用すると、ロジックが非常に複雑になります。transactionscope は、すべてを把握できるほどインテリジェントではありません。

于 2013-01-04T10:44:00.893 に答える