質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.36%

[ASP.NET MVC5]1行1行ずつViewModelに値を入れている為、処理が重くなる現象を解決したい

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,353

widget11

score 192

環境
windows
ASP.NET MVC5
C#6.0
visualstudio community 2017

ASP.NET MVC5でのアプリケーション制作のトレーニングとして採用システムを作っていますが動作スピードが非常に悪いため改善したいです。
特に遅い箇所が候補者一覧画面で、DBにあるt_entryテーブルから値を持ってきて、それを表示用に加工する為(t_entry以外のモデルの属性を使いたかったりする為)foreachでt_entryのレコードを取り出しview用のモデルviewmodelのインスタンスに一つ一つの属性を追加している状態である為。非常に動作が遅くなっています。
全ての属性や処理を羅列しているとキリがないため、一部を端折りますがどのようなアプローチをとった方が良いかお教え頂くと有難いです。
現状大方のトランザクション処理等全てをコントローラーに書いてあり、MVCの設計に沿っていない形となりますがご容赦ください。

#candidateコントローラークラス/indexアクション
 public class CandidateController : BaseController
    {
        private TestEntities db = new TestEntities();
・
・//省略//候補者テーブルにある削除フラグの立っていない候補者を全て取ってくる
  var t_entry = _base.t_entry.Where(a => a.DelFlg == 0).OrderByDescending(a => a.EntryId);

//1行1行取ってきた候補者に対してforeachで一人一人取り出し、view用のモデルのプロパティに値を入れていく
            foreach (var list in t_entry)
            {
                var phaseId = db.t_selection.Where(x => x.EntryId == list.EntryId).OrderByDescending(x => x.SelectionId).Select(x => x.PhaseId).FirstOrDefault();
                string adoptCost = list.AdoptCost != null ? String.Format("{0:#,0}", list.AdoptCost) : "";


                CandidateListViewModel candidateData = new CandidateListViewModel
                {
                    CandidateId = list.EntryId,
                    CandidateName = list.CandidateName,
                    CandidateNameKana = list.CandidateNameKana,
                    JobCategoryName = masterTable.GetJobCategory(list.JobCategoryId),
                    JobCategoryId = list.JobCategoryId,
                    EntryRouteName = masterTable.GetEntryRoute(list.EntryRouteId),
                    CandidateLocationID = list.LocationId,
                };
                candidateList.Add(candidateData);
            }
・
・//省略
・
  return View(models);
   }
//DBファーストで作成したt_entryモデルクラス
public partial class t_entry
    {
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
        public t_entry()
        {
            this.t_document = new HashSet<t_document>();
            this.t_selection = new HashSet<t_selection>();
        }

        public int EntryId { get; set; }
        public int SelectionStatusId { get; set; }
        public int JobCategoryId { get; set; }
        public int EntryRouteId { get; set; }
        public Nullable<int> LocationId { get; set; }
  }
//view用のCandidateListViewモデルクラス
 public class CandidateListViewModel
    {
        public int CandidateId
        {
            get;
            set;
        }

        public string CandidateName
        {
            get;
            set;
        }
        public string CandidateNameKana
        {
            get;
            set;
        }

        public string CandidateLocationName
        {
            get;
            set;
        }

        public int? CandidateLocationID
        {
            get;
            set;
        }

省略為、一部属性があったりなかったり(あとdataがdateって名前になってたり)しますが、、、現状このような形でviewmodelに値を入れていき、この後の処理でviewに対してモデルを渡しております。
長くなりましたが宜しくお願い致します。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • SurferOnWww

    2019/03/22 16:55

    質問者さんが先に立てたスレッド https://teratail.com/questions/176949 が放置状態ですが、クローズするまでフォローしていただけませんか。

    キャンセル

  • widget11

    2019/03/22 17:43

    クローズ致しました。ご対応遅れてしまい申し訳ございません。

    キャンセル

  • SurferOnWww

    2019/03/22 18:09

    対応いただきありがとうございました。

    キャンセル

  • SurferOnWww

    2019/03/22 18:22

    コードは省略されていて定義不明な変数などが多く、どこがボトルネックになっているのかもわからず、答えるのが難しいです。

    ボトルネックの部分だけを示す完全な Controller と View のサンプルを作って、そこをどう改善するかというような議論ができるようにしていただければと思うのですが、可能でしょうか?

    キャンセル

回答 2

checkベストアンサー

0

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/03/22 16:40 編集

    ご回答ありがとうございます。
    一応こちらのライブラリは導入しておりページング機能自体は実装しているのですが、以上のように全件取ってきたあとにページング処理を行っています。
    方向性としては全てではなくこれを20件なり50件なりずつ取ってきて、view側に渡すといった必要があるということでしょうか?

    キャンセル

  • 2019/03/22 16:43

    そのほうが良いと思います。

    キャンセル

0

実際にかかっている時間を計測するなどして、どこがボトルネックになっているのか調べていただく必要があると思いますが・・・

質問に書かれている Controller のコードを眺めて想像すると、一行処理するたびに SQL Server にクエリを投げなければならないというような処理を行っていて、それを foreach (var list in t_entry) ループを回す回数行う ⇒ 結果、Web アプリと SQL Server とのラウンドトリップが非常に多くなるのがボトルネックになってるような気がします。

しかし、コードは省略されていて定義不明な変数などが多く、ラウンドトリップを減らすためにどう改善できるかは分かりません。そもそも、そこがホントにボトルネックなのかもわかりませんし。

実際にラウンドトリップが多いのがボトルネックと確認できたら、そのあたりの部分の完全なサンプルを作って追加情報として提供されてはいかがですか。

その際、ASP.NET MVC とは無関係な C# + EDM + Linq to Entities だけのサンプルにできれば、ASP.NET を知らない人も回答できるので、回答が集まりやすいと思います。

【追伸】

質問に書かれている「DBファーストで作成したt_entryモデルクラス」を見る限りナビゲーションプロパティは使っていないようですが、それも省略されていて実は使っているとすると、そこでもクエリは SQL Server に投げられますのでラウンドトリップが増える原因になります。注意してください。

N+1 問題と言うようです。詳しくは以下の記事を見てください。回避策も記載されています。

N+1問題を回避せよ! LINQから出力されるSQLを見てみよう&遅延ローディングの光と闇
https://codezine.jp/article/detail/8415

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.36%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • トップ
  • C#に関する質問
  • [ASP.NET MVC5]1行1行ずつViewModelに値を入れている為、処理が重くなる現象を解決したい