2016-06-28 12 views
1

私は古いプロジェクトを作業に費やしています。私は現在いくつかのWeb APIを見ています。 1つのAPIが特に低速で実行されているため、問題がデータサービスにあります。具体的には、ストアドプロシージャの結果をドメインモデルにマップしようとするラムダメソッドです。コードの単純なバージョン。エンティティ・フレームワークのストアド・プロシージャの結果をドメイン・モデル

public IEnumerable<DomainModelResult> GetData() 
{ 
    return this.EntityFrameworkDB.GetDataSproc().ToList() 
      .Select(sprocResults=>sprocResults.ToDomainModelResult()) 
      .AsEnumerable(); 
} 

これは簡易版ですが、それをプロファイリングした後、私は大きなハングアップは、ラムダ関数である見つけました。私はこれがEFContextがまだ開いていて、いくつかの奇妙なエンティティフレームワークが起きていると仮定しています。

問題Entity Framework(インターン)には比較的新しいし、内部の仕組みには無知です。誰かがなぜこれがとても遅いのか説明できますか?私はそれが非常に速くなければならないと感じます。DomainModelResultはPOCOであり、ToDomainModelResultではsetterメソッドのみが使用されています。

編集: 私はToList()と思っていましたが、私は別の説明を考えることができなかったので、自分自身を疑い始めました。すべてのToDomainModelResult()ものは非常に簡単です。何かのようなもの。

public static DomainModelResult ToDomainModelResult(SprocResult source) 
{ 
    return new DomainModeResult 
    { 
    FirstName = source.description, 
    MiddleName = source._middlename, 
    LastName = source.lastname, 
    UserName = source.expr2, 
    Address = source.uglyName 
    }; 
} 

そのシンプルなセッターの数だけ、私は問題を引き起こすモデルは17のプロパティを持っていると思います。これが行われているのは、プロジェクトが古いデータベースであり、ストアドプロシージャの名前がわかりにくいためです。また、dataservices内のストアドプロシージャを簡単に切り替えることは簡単で、プロジェクトの残りの部分を分割することはありません。

編集:2何らかの理由でToArrayを使用し、linqステートメントを分割すると、プロシージャー結果からドメインモデル結果への割り当てが非常に高速になります。今度はdataserviceメソッド全体が高速ですが、それは奇妙です、私は時間の残りの部分がどこに行ったのかわかりません。

これは私が元々考えていたより難解な質問かもしれません。私の質問は答えられていませんが、問題はもう解決されていません。すべての返事をいただきありがとうございます。私はこれを未回答のままにしておきます。

編集3:削除するにはこの質問にフラグを立ててください削除できません。私は問題を見つけましたが、それは私の元の質問とはまったく無関係です。私が質問したときに問題を誤解しました。速度の向上私は、コンパイラの最適化とプロファイラでのコードの実行にまで挑戦しています。本当の問題は私のラムダではなく、コンテキストが閉じられたり、オブジェクトにアクセスしたりしてデータ検証が行われていたときに、エンティティフレームワークによって呼び出された動的ラムダであった。 GetString、GetInt32、およびISDBNullが最も多くの時間を食べていました。だから私は、マイクロソフトがこれらのメソッドを最適化していると仮定しており、これをスピードアップする唯一の方法は、プロシージャ内でnull可能でない変数を作成する可能性があるからです。この質問は誤解を招くので、私はそれがここに属しているとは思わないし、人々を混乱させるだけです。ごめんなさい。

+0

に依存)SQLクエリを実行し、完了しています。ラムダに問題がある場合、おそらくToDomainModelResult()とEFの何かが関係しています。そのメソッドのコードを表示できますか? –

答えて

1

コードを分割して、どちらが時間がかかるかを確認する必要があります。

public IEnumerable<DomainModelResult> GetData() 
{ 
    var lst = this.EntityFrameworkDB.GetDataSproc().ToList(); 
    return lst 
      .Select(sprocResults=>sprocResults.ToDomainModelResult()) 
      .AsEnumerable(); 
} 

私はGetDataSprocプロシージャがほとんどの時間を費やしていると確信しています。

更新 可能であれば、メモリに60,000行を取得するのではなく、SQL側でより多くの作業を行う方がよいでしょう。いくつかの可能な解決策:

  • あなたがページングを行う(トップとスキップ)、この情報を表示する必要がある場合は
  • あなたが任意のフィルタリングを行っているか、メモリ内の行を取得した後、何かを計算するか、グループ化されている場合は、あなたにそれを行いますストアドプロシージャ
  • ネット側、あなたがあなたの第二部にyieldを使用できるかもしれIEnumerable戻ってきているように、とすぐにToListメソッド(コールとして、あなたのアーキテクチャに
+0

私はストアドプロシージャは常に同じものだと思っていましたが、.netプロファイラを使用するとストアドプロシージャは約4分の1かかり、ラムダは約10秒かかります。 – Tenderdude

+0

私は分割してストップウォッチでチェックしますとにかく、しかし、SQLマネージャ上でプロシージャを実行するとかなり速いようです。 – Tenderdude

+0

何行目について話していますか? – MJK

関連する問題