1

この投稿によると、呼び出しごとにデータコンテキストを使用しているため、WCFサービスの各メソッドで、usingブロックを使用して新しいデータコンテキストを作成します。

しかし、私はこのように機能するという形でいくつかの疑問を持っています。

たとえば、リポジトリからgetAllCLients()メソッドを使用してデータベースのすべてのクライアントを取得し、サービスがそのメソッドを呼び出すクライアントにすべてのクライアントのリストを送信します。次に、ユーザーはそれらのいくつか、たとえば3つの情報を変更します。変更クライアントは、おそらく変更されたクライアントを持つリストに追加できます。

この3つのクライアントを更新する場合は、変更されたクライアントのリストを受け取るメソッドupdateClients()を呼び出すことができます。各メソッドごとに新しいデータコンテキストを使用する方法、updateCients()で、エンティティなしで新しいdataContextを取得するため、次の手順に従う必要があると思います。

1.-更新するクライアントを持つ新しいデータコンテキストを作成します。そのための条件を指定する必要があります。これは追加の操作であるため(以前はgetAllClients()メソッドを使用してクライアントを取得しました)、クライアントを再度取得する必要があります。

2.- DBSetのクライアントコレクション(私はEF 4.1を使用)をスローして、情報を変更します。これにより、クライアントアプリケーションから受け取ったリストもスローすることになります。だから私は2つのリストを投げに行かなければなりません。これにはリソースが必要です。

3.-変更を保存します。これはとにかく必要なので、これ以上の作業は必要ありません。

ステップ2を簡単に行う方法はありますか?変更したクライアントからデータコンテキストのクライアントに値を渡すためのメソッドがdataContextに存在しますか?私はPOCOエンティティを使用していますが、おそらくそれを行う簡単な方法があります。

他の質問は並行性についてです。EFを許可するペシミスティックな同時実行性(たとえば、タイムスタンプフィールドを使用)で同時実行性を制御する場合、クライアントごとにupdateClient()を呼び出すか、すべてのクライアントでリストを渡す方がよいでしょうか?つまり、リストをパラメーターとして使用する場合、1つのクライアントで同時実行の問題が発生すると、たとえば2番目のクライアントは正しく更新されますが、2番目のクライアントは正しく更新されません。一部のクライアントに問題があることをユーザーに通知するにはどうすればよいですか?

再開するには、データコンテキストが短い場合に更新を行うための最良の方法を知りたいと思います。

ありがとう。ダイムロック。

4

1 に答える 1

4

サービスが切断されたシナリオであるため、クライアントが変更されたレコードを返す場合は、変更されたものとして処理する必要があります。そのためにデータベースからすべてのレコードをロードする必要はありません。

public void SaveClients(List<Client> modifiedClients)
{
    using (var context = new Context())
    {
        modifiedClients.ForEach(c => 
           {
               context.Entry(c).State = EntityState.Modified;
           });
        context.SaveChanges(); 
    }
}

呼び出しごとのサービスを使用していて、すべてのサービス操作にコンテキストが必要な場合、サービスインスタンスはサーバーの単一のサービス呼び出しにのみ存在するため、コンテキストインスタンス化をサービスコンストラクターに移動できます=usingすべての呼び出しに必要なわけではありません。IDisposableその場合は、コンテキストを破棄するためにサービスに実装することを忘れないでください。

他の質問は並行性についてです。EFを許可するペシミスティックな同時実行性(たとえば、タイムスタンプフィールドを使用)で同時実行性を制御する場合、クライアントごとにupdateClient()を呼び出すか、すべてのクライアントでリストを渡す方がよいでしょうか?

EFは、すぐに使用できる悲観的な並行性をサポートしていません。タイムスタンプの使用は、他のユーザーがレコードを使用できるようにするため、楽観的並行性です。悲観的な同時実行性は、他のクライアントが更新のためにロックされたレコードを選択できないアプリケーションロジックです。

同時実行性はレコードごとに解決されますが、この場合の問題はトランザクションです。を呼び出すSaveChangesたびに、データベース内のすべての変更を処理するために使用されるトランザクションが発生します。したがって、変更されたレコードのいずれかが最新でない場合、同時実行例外が発生し、トランザクション全体がロールバックされます=レコードは更新されません。

変更されたレコードのリストをサービスに渡すことで問題を解決できますが(クライアントとサービス間のラウンドトリップを減らすことがベストプラクティスです)、すべてのレコードを呼び出すことSaveChangesで各レコードを個別に処理できます。とにかく、これは非常に慎重に検討する必要があります。これは、への各呼び出しSaveChangesが個別の作業単位のようなものであるためです。本当に必要なものですか。

ところで。ベストプラクティスは、サービスを統計なしにすることです。サービス呼び出し間でデータを維持することは避ける必要があり、この例では実際にはデータを必要としません。

于 2012-04-15T19:23:12.313 に答える