0

WCF Data Services を使用する Silverlight アプリケーションがあります。ロギング機能を追加したいと考えています。新しい行が生成されると、この新しい行の主キーもロギング テーブルに記録されます。行の生成とロギングは、同じトランザクション内で発生する必要があります。主キーは、データベースを介して (IDENTITY キーワードを使用して) 生成されます。

これは、例を使って説明するのが一番良いかもしれません。ここでは、新しいCustomer行を作成し、同じトランザクションで Customer の主キーをAuditLog行に書き込みます。この例では、シック クライアントと Entity Framework を使用しています。

    using (var ts = new TransactionScope())
    {
        AuditTestEntities entities = new AuditTestEntities();
        Customer c = new Customer();
        c.CustomerName = "Acme Pty Ltd";
        entities.AddToCustomer(c);
        Debug.Assert(c.CustomerID == 0);
        entities.SaveChanges();
        // The EntityFramework automatically updated the customer object
        // with the newly generated key
        Debug.Assert(c.CustomerID != 0);
        AuditLog al = new AuditLog();
        al.EntryDateTime = DateTime.Now;
        al.Description = string.Format("Created customer with customer id {0}", c.CustomerID);
        entities.AddToAuditLog(al);
        entities.SaveChanges();
        ts.Complete();
    }

Entity Framework を使用してシック クライアントを開発する場合、これは些細な問題です。

ただし、Silverlight および ADO.NET データ サービスを使用すると、次のようになります。

  • SaveChanges は非同期でのみ呼び出すことができます
  • TransactionScope が利用可能かどうかわかりません
  • 生成されたキーをクライアントに反映できるかどうかはわかりません編集: Alex Jamesによると、それらは実際にクライアントに反映されます

それで、これは可能でしょうか?

4

1 に答える 1

4

短い答え: いいえ、これは不可能です

そして:

  1. 生成されたキーはクライアントに反映されます。
  2. DataServiceContext を使用して、1 つの SaveChanges 操作を処理できます。SaveChanges ( SaveChangesOption.Batch )

しかし、残念ながら、あるリクエストを別のリクエストのレスポンスに関連付けて、両方を 1 つのトランザクションにラップすることはできません。

でも...

AuditLog から派生した CustomerAuditLog メソッドを作成してモデルを変更した場合:

// Create and insert customer ...
// Create audit log and relate to un-insert customer
CustomerAuditLog al = new CustomerAuditLog(); 
al.EntryDateTime = DateTime.Now; 
al.Description = string.Format("Created customer with {Customer.ID}");
// assuming your entities implement INotifyPropertyChanging and you are using
// the Data Services Update to .NET 3.5 SP1 to use DataServiceCollection 
// to notify the DataServiceContext that a relationship has been formed. 
//
// If not you will manually need to tell Astoria about the relationship too.
al.Customer = c; 
entities.AddToAuditLog(al); 
entities.SaveChanges();

また、基礎となる DataSource やデータベースに何らかのロジックを深く配置して、{Customer.ID} を適切な値に置き換えます。

2 つの挿入が同じトランザクションで発生し、1 つ (CustomerAuditLog) が別の (Customer) に依存している場合、基になるデータ ソースによって適切に順序付けされる必要があるため、機能させることができる場合があります。

しかし、このアプローチは一種のハックであることがわかるように、考えられる監査メッセージごとに Type は必要ありません。そして...うまくいかないかもしれません。

お役に立てれば

アレックス

データ サービス チーム、マイクロソフト

于 2010-01-12T23:48:21.410 に答える