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

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

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

LINQ

LINQとはLanguage INtegrated Queryの略で、「統合言語クエリ」という意味です。C#やVisual Basicといった言語のコード内に記述することができるクエリです。

ASP.NET MVC Framework

ASP.NET MVC Frameworkは、MVCパターンをベースとした、マイクロソフトのウェブアプリケーション開発用のフレームワークです。

Q&A

解決済

2回答

2461閲覧

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

widget11

総合スコア221

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

LINQ

LINQとはLanguage INtegrated Queryの略で、「統合言語クエリ」という意味です。C#やVisual Basicといった言語のコード内に記述することができるクエリです。

ASP.NET MVC Framework

ASP.NET MVC Frameworkは、MVCパターンをベースとした、マイクロソフトのウェブアプリケーション開発用のフレームワークです。

0グッド

0クリップ

投稿2019/03/22 05:24

編集2019/03/22 08:40

環境
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に対してモデルを渡しております。
長くなりましたが宜しくお願い致します。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/03/22 07:55

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

2019/03/22 08:43

クローズ致しました。ご対応遅れてしまい申し訳ございません。
退会済みユーザー

退会済みユーザー

2019/03/22 09:09

対応いただきありがとうございました。
退会済みユーザー

退会済みユーザー

2019/03/22 09:22

コードは省略されていて定義不明な変数などが多く、どこがボトルネックになっているのかもわからず、答えるのが難しいです。 ボトルネックの部分だけを示す完全な Controller と View のサンプルを作って、そこをどう改善するかというような議論ができるようにしていただければと思うのですが、可能でしょうか?
guest

回答2

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

投稿2019/03/23 03:54

編集2019/03/28 01:11
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

投稿2019/03/22 06:33

hihijiji

総合スコア4150

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

widget11

2019/03/22 07:40 編集

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

2019/03/22 07:43

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問