すべてが機能します。これをさらに最適化しようとして問題が発生しました。リポジトリの方法は、私が望むように機能します。それは素晴らしく、高速です。Download Hunters コントローラー アクションに到達すると、すべての Temp 割り当てが少し遅くなります。特に HunterFields エリアでは、Hunter をフィールドに結合する結合テーブルです。(これらは JobHunters とそのカテゴリです。何らかの理由で役立つ場合)。私は 100,000 人のハンターを扱っていますが、それぞれのハンターのカテゴリには 3 ~ 14 のフィールドがあります。
リポジトリ方式
public List<Hunter> FetchAllHunters(Member user, DateTime? BeginDate = null, DateTime? EndDate = null, IEnumerable<int> FieldIDs = null)
{
StringBuilder SQLQuery = new StringBuilder();
// This main Query stringbuilder will be appended and formatted using checks against certain params.
SQLQuery.AppendFormat("Select * FROM Hunters WHERE CompanyID = '{0}'", user.CompanyID);
if (BeginDate != null && EndDate != null) /* I like Between, that was I don't have to do Enddate >= CreateDate >= BeginDate */
SQLQuery.Append(" AND Hunters.CreatedDate BETWEEN @BeginDate and @EndDate");
if (FieldIDs != null && FieldIDs.Count() > 0 && !FieldIDs.Contains(0))
SQLQuery.AppendFormat(" AND EXISTS (SELECT 1 FROM [dbo].[FieldsHunters] AS [FieldHunt] WHERE ([Hunters].[ID] = [FieldHunt].[HunterID]) AND ([FieldHunt].[FieldID] IN ({0})))", String.Join(", ", FieldIDs));
return dbContext.Hunters.SqlQuery(SQLQuery.ToString(),
new SqlParameter("@BeginDate", BeginDate),
new SqlParameter("@EndDate", EndDate)).AsNoTracking().ToList();
}
コントローラ (問題のある場所)
public ActionResult DownloadHunters(HunterStatsViewModel VM)
{
List<Hunter> Hunters = db.FetchAllHunters(user, VM.BegnDate, VM.EndDate, VM.FieldIDs);
List<List<string>> Temp = new List<List<string>>(){
new List<string>() { "Hunter ID" }
};
Temp[0].AddRange(Hunters.Select(x => x.ID.ToString()).ToList());
if (VM.ID == true)
Temp = AddColumnRows(Temp, "ID", Hunters.Select(x => x.ID.ToString()).ToList());
if (VM.HunterName == true)
Temp = AddColumnRows(Temp, "Hunter Name", Hunters.Select(x => x.FullName).ToList());
if (VM.Address == true)
Temp = AddColumnRows(Temp, "Address", Hunters.Select(x => x.Address1).ToList());
if (VM.ContactPhone == true)
Temp = AddColumnRows(Temp, "Home", Hunters.Select(x => x.Phone1).ToList());
if (VM.WorkPhone == true)
Temp = AddColumnRows(Temp, "Work", Hunters.Select(x => x.WorkPhone).ToList());
if (VM.MobilePhone == true)
Temp = AddColumnRows(Temp, "Cell", Hunters.Select(x => x.Phone2).ToList());
if (VM.ContactFax == true)
Temp = AddColumnRows(Temp, "Fax", Hunters.Select(x => x.Fax).ToList());
if (VM.ContactEmail == true)
Temp = AddColumnRows(Temp, "Email", Hunters.Select(x => x.Email).ToList());
/* This area takes 45 seconds! */
if (VM.EmploymentField == true)
Temp = AddColumnRows(Temp, "Employment Field", Hunters.Select(x => String.Join(", ", x.Fields.Select(q => q.Field.Name).ToList())).ToList());
if (VM.Citizenship == true)
Temp = AddColumnRows(Temp, "Status", Hunters.Select(x => x.HunterStatus != null ? x.HunterStatus.Name : " ").ToList());
if (VM.AvailDate == true)
Temp = AddColumnRows(Temp, "Availability Date", Hunters.Select(x => String.Format("{0}/{1}", x.AvailableStartMonth.ToString(), x.AvailableStartYear.ToString())).ToList());
/* Takes about 5-10 seconds */
if (VM.Licensures == true)
Temp = AddColumnRows(Temp, "Licensures", Hunters.Select(x => String.Join(", ", x.Tempes.Where(y => y.Licensed == true).Select(z => z.Tempe.Code).ToList())).ToList());
if (VM.Education == true)
Temp = AddColumnRows(Temp, "Education", Hunters.Select(x => x.EducationDescription).ToList());
if (VM.Gender == true)
Temp = AddColumnRows(Temp, "Gender", Hunters.Select(x => (x.Gender == true ? "Male" : (x.Gender == false ? "Female" : "N/A"))).ToList());
// Date doesn't need a check.
Temp = AddColumnRows(Temp, "Date Poste", Hunters.Select(x => x.CreatedDate.ToString()).ToList());
TempData["Temp"] = Temp;
TempData["FileName"] = "HunterDownloads";
return RedirectToAction("Download");
}
フィールディングの方法
public List<List<string>> AddColumnRows(List<List<string>> Stats, string field, List<string> datas)
{
Stats.Add(new List<string>() { field });
Stats[Stats.Count() - 1].AddRange(datas);
return Stats;
}
ダウンロードビュー
@model HunterStatsViewModel
@{
/* I'm being bad with tempdata and reassigning the data. Screw teh rules I have tea and crumpets. */
TempData["FileName"] = Model.FileName;
TempData["ReportRange"] = Model.Report;
TempData["Temp"] = Model.Temp;
}
@{
Response.ClearContent();
Response.AddHeader("content-disposition", String.Format("attachment;filename={0}.xls", Model.FileName));
Response.Buffer = true;
Response.Charset = "UTF-8";
Response.ContentType = "application/application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.Write("<table width='100%' border='1'>");
if (Model.Report != null)
{
Response.Write(String.Format("<tr><td colspan='2'>{0}<td></tr>>", Model.Report)); // In case they want to add a report header or such.
}
for (int j = 0; j < Model.Temp[0].Count(); j++)
{
Response.Write("<tr>");
for (int i = 0; i < Model.Temp.Count(); i++)
{
Response.Write(string.Format("<td>{0}</td>", Model.Temp[i][j]));
}
Response.Write("</tr>");
}
Response.Write("</table>");
Response.End();
}
これを最適化する方法を見つけるために、私は何日も探し回っています! たくさんのテストをしても。ただし、統計情報を Excel ファイルに適切に保存するには、まだ約 60 秒かかります。15秒でも嬉しい!O' Mighty SOers ありがとうございます。