1

この質問は、thatの続編のようなものです。WCFデータのシリアライゼーション:より速く進むことができますか?

何らかの種類のデータで動作するWCFサービスを構築したい場合は、高速かつ効率的であることが望まれます。これを達成するためには、SQL Serverなどのデータストレージバックエンドからデータを要求したWCFクライアントまで、データロードのすべてのセグメントを可能な限り高速に処理する必要があります。

Slaumaなどのコメントをいただき感謝していますが、Entity Frameworkの(最初の)大きなクエリの時間がかかる部分はオブジェクトのマテリアライゼーションであり、エンティティをコンテキストデータベースからの結果が返されたとき。私たちは、後続のクエリですべての処理がはるかに高速になることを確認しました

これらの大きなクエリが読み取り専用操作として使用されると仮定すると、EF MergeOptionNoTrackingに設定すると、最初のクエリのパフォーマンスが向上するとの結論に達しました。我々がNoTrackingで行ったことは、EFに、同じキーを持っていても、データベースから取り出されたレコードごとに別のオブジェクトを作成するようにEFに指示していました。これにより、クエリに.Include()文があると追加の処理が行われ、より大きなサイズのデータ​​が返されます。我々は.Include()文の数に応じて、クエリ速くする(そしておそらく最初のものだけあっても、私たちは本当にNoTrackingオプションを使用することにより、当社の原因を助けなかった -

データは、我々は簡単に自分自身を頼むことができるように大きいかもしれ複数の.Include()ステートメントを使用したNoTrackingオプションを使用しない後続のクエリは、サーバーからデータが返されたときにさらに多くのオブジェクトが作成されるため、より高速に実行されるためです。

最大の問題は、この量のデータを効率的にシリアル化し、クライアントでデシリアライズする方法です。私はDataContractSerializerPreserveObjectReferencestrueに設定しています(私はEF 4.xで生成されたPOCOをクライアントに送信しています。逆も同様です)、より多くのデータを生成したいのですか(NoTracking)。正直言って、私はデータが.Include()経由で取得されたナビゲーションプロパティを含まない〜11.000オブジェクトのNoTrackingオプションのクエリから生成され、クライアント側にまだ到着していないことを確認しました。前回私がこれを取り除こうとしたときに、00:10:00のタイムアウトが発生しました(!)

この壁をまだ読んでいるなら、この状況を解決する方法を教えてください。受け入れ可能な結果を​​得るために使用するシリアライザはどれですか?現在、NoTrackingオプションを使用しない場合、ローカルマシンのwsHttpBindingのようなカスタムバインディングを介して〜11.000のシリアル化、トランスポートおよび非シリアル化が約5秒かかります。私にとって恐ろしいのは、この大きなテーブルが最終的に〜500,000レコードを含む可能性が高いということです。

答えて

2

オブジェクトのビューモデルを作成し、selectステートメントで投影を行うことを検討しましたか。それは速いので、たくさんのようになります。

var result = from person in DB.Entities.Persons 
    .Include("District") 
    .Include("District.City") 
    .Include("District.City.State") 
    .Include("Nationality") 
    select new PersonViewModel() 
    { 
     Name = person.Name, 
     City = person.District.City, 
     State = person.District.City.State 
     Nationality = person.Nationality.Name 
    }; 

これはPersonViewModelための平坦化データを保持するためのViewModelクラスを作成することが必要となります。

データベースビューを作成し、そこから直接Entity Frameworkを選択させることで、スピードをさらに高めることができます。

フロントエンドが集計して500でグリッドを作成したい場合。000レコードを取得したら、Webサービス層を完全に削除し、DataReaderを使用してプロセスを高速化します。 Entity FrameworkおよびWCFは、適切なパフォーマンスでデータを変換するのには適していません。あなたは基本的にここでやっていることは次のとおりです。

データベース - > TDS - > .NETオブジェクト - > XML - >プレーンテキスト - > XML - > .NETオブジェクト - > UI

このものの - > TDS - > UI

その後、あなたのビジネスロジック内のエンティティへの変更を処理するためにEntityFramworkを使用

データベース:簡単に減らすことができました。これは、コマンドとクエリの分離パターンに沿っています。データの高性能クエリに適したテクノロジを使用して、それをアプリケーションに直接リンクします。その後、コマンド戦略を使用してビジネスロジックを実装します。すぐにあなたが、ユーザーが本当に気付かずに迅速なフィルタリングを実装することができ、あなたのデータを照会するために使用することができますよう

のODataサービスは、データを直接あなたのUIをリンクするより良い方法を提供することがあります。

セキュリティ設定がODataのか、SQLデータベースに直接アクセスを通じて直接照会を禁止している場合は、オブジェクトを自分でマテリアライズ考えます。ビューまたはクエリから直接データを選択し、IDataReaderを使用してViewModelに直接入力します。それはおそらくあなたに最高のパフォーマンスを与えるでしょう。

EFは、大規模なデータセットのために切り取られていないため、特に作成したEntity Frameworkのに代わるものがたくさんあります。 FluentDataDapperDotNet,MassiveまたはPetaPocoを参照してください。大規模でフラットなデータクエリを処理するには、これらをエンティティフレームワークと並べて使用することをお勧めします。

+0

私は間違いなくViewModelsを使うべきだと思います。私の現在のデザインは、より良いエンドユーザー経験に傾いています。 DGVには、ナビゲーションプロパティオブジェクトを含む結果セット全体が含まれているため、ユーザーがParentForm.GetCurrentObject()呼び出しの編集を「編集」してコントロールにバインドすると、編集されます。しかし、私はDGVのためのViewModelsの使用と、編集フォームのBackgroundWorkerからのProxy.GetObjectByID()の呼び出しを検討します。先端に感謝します。 –

+0

ODataについて、またはSQLデータベースへの直接アクセスについては、これは問題ありません。利用可能な多くのセキュリティ機能のため、私は「通常の」WCFサービスを好む。 FluentData、Dapper、Massive、またはPetaPocoを使用するための提案については、EntityFrameworkを使用する私の喜びは、エンティティへのLINQがSQLサーバー上にある間にエンティティに直接アクセスできることです。これらの他のソリューションでは、自分のコードで醜い(味わいの)SQLやSQLのような構文を使用する必要があります。 –

+0

私はあなたの問題をよく見ているEF Linqの構文から離れることで理解します。しかし、あなたがより良いパフォーマンスを持ち、ViewModel/Projectionを使って十分に助けにならない場合は、すべてのエンティティクラスに 'Equals'と' HashCode'を実装し、シリアライザがこれを拾いなさい。 – jessehouwing

0

RIAアプリケーションでBsonのJson.Netの実装を使用します。 More info here.

私がデータベースから読み出され、行をシリアライズとして、IEnumerableをを返すもたらします。私は速度が受け入れられるとわかり、約20の特性を持つエンティティを返します。この方法では、サーバー上の同時メモリー使用を最小限に抑える必要があります。

+0

あなたのソリューションでは、私のPOCOクラスに特別な属性を追加する必要がありますか、それともプラグインして動作させるだけですか?私はEFで生成されたPOCOエンティティを使用しているため、これらの定義を変更することはできません。モデルを再生成すると、すべての変更が失われます。 –

+1

異なるコードを生成するようにT4テンプレートを変更することができます。また、必要に応じて部分クラスに変更を貼り付けることもできます。 – jessehouwing

+0

良いコメント、私は今T4テンプレートが部分クラスを生成することに気づいた。このJson.Netのシリアライザのパフォーマンスは[protobuf-net](http://code.google.com/p/protobuf-net/)とどのように比肩しますか? –

0

私は、様々な口コミやパフォーマンスのベンチマークを見て、集まった内容に基づいて、私は、シリアライザとしてprotobuf-netを選ぶだろう。それは私のサービス構成に差し込むことができるかどうかは設計上の問題です。その詳細情報here

完全にこの質問への答えは、jessehouwingが最良の答えを持っていたと認められたとして、私はそれをマーキングしていませんが。

関連する問題