如何解决迭代ASP.net时仅使用数据库的一部分-遍历整个数据库会减慢其速度
我有一个通过ASP.net的程序。直到数据库获得大约100个条目,然后它变得非常缓慢,它才能很好地工作。
我知道原因,但不知道如何解决。
该程序使大型911调度中心的员工可以从控制台上注册休息,午餐和休息室休息时间。他们从下拉列表中选择自己的名字和位置。当他们单击提交时,它将信息添加到数据库。然后,该程序遍历数据库,以找到活动时间/午餐/休息室休息时间,以找到活动时间并将其显示在表格中。
重要的是,当某人进入列表时,该表会快速更新,以便所有控制台的所有人都知道某人何时将其添加到该表中。因此,我让程序每5秒迭代一次db,以更新谁在列表中。它对少于100个条目感到满意,但对更多条目却做得不好-这是有道理的-在这么短的时间内进行大量迭代。
我有两个可能的想法,但我不知道如何使它们起作用,并且Google并没有太大帮助。
一个想法是仅导入过去两天的数据,并对其进行迭代。如果没有像现在这样迭代,我不确定如何使它完成。
另一个想法是我必须将所有内容保存到列表中,同时将其保存到数据库中,以便仅通过内存而不是数据库进行迭代。不过,我不知道如何将多个字段存储到该列表中。也许是字典?我不知道。我不知道那有多实用。
下面是一些代码:
控制器:
[System.Web.Http.HttpPost]
public ActionResult CreateLunch(Lunch lunch)
{
try
{
lunch.TimeEntered = DateTime.Now;
db.Lunches.Add(lunch);
db.SaveChanges();
var breaksList = db.Breaks.ToList();
foreach (var item in breaksList)
{
Break mdl = new Break();
mdl.BreakID = item.BreakID;
mdl.Employee = item.Employee;
mdl.TimeEntered = item.TimeEntered;
mdl.TimeCleared = item.TimeCleared;
mdl.PositionID = item.PositionID;
mdl.EmpSent = item.EmpSent;
if (db.Breaks != null)
{
db.Breaks.Add(mdl);
}
db.Breaks.Add(mdl);
}
var employee = db.Employees.ToList();
foreach (var item in employee)
{
Employee mdl = new Employee();
mdl.EmployeeID = item.EmployeeID;
mdl.FirstName = item.FirstName;
mdl.LastName = item.LastName;
mdl.NotActive = item.NotActive;
mdl.Force = item.Force;
mdl.displayName = item.displayName;
if (db.Employees != null)
{
db.Employees.Add(mdl);
}
}
var dthmodel = db.Dths.ToList();
foreach (var item in dthmodel)
{
Dth mdl = new Dth();
mdl.DthID = item.DthID;
mdl.Employee = item.Employee;
mdl.TimeCleared = item.TimeCleared;
mdl.TimeEntered = item.TimeEntered;
mdl.PositionID = item.PositionID;
mdl.EmpSent = item.EmpSent;
if (db.Dths != null)
{
db.Dths.Add(mdl);
}
}
var lunchModel = db.Lunches.OrderBy(x => x.LunchTime);
foreach (var item in lunchModel)
{
Lunch mdl = new Lunch();
mdl.Employee = item.Employee;
mdl.LunchID = item.LunchID;
mdl.PositionID = item.PositionID;
mdl.LunchTime = item.LunchTime;
mdl.LongerLunch = item.LongerLunch;
mdl.Double = item.Double;
mdl.TimeEntered = item.TimeEntered;
mdl.EmpSent = item.EmpSent;
mdl.TimeCleared = item.TimeCleared;
if (db.Lunches != null)
{
db.Lunches.Add(mdl);
}
}
var positionModel = db.Positions.ToList();
foreach (var item in positionModel)
{
Position mdl = new Position();
mdl.PositionID = item.PositionID;
mdl.PositionName = item.PositionName;
if (db.Positions != null)
{
db.Positions.Add(mdl);
}
}
var date = DateTime.Now;
var dateOffset = DateTime.Now.AddDays(-1);
ViewBag.EmployeesNames = db.Employees.Where(x => x.NotActive == false).OrderBy(x => x.displayName).ToList();
ViewBag.PositionNames = db.Positions.ToList();
ViewBag.LunchTimes = db.Lunches.Where(x => x.TimeEntered <= date && x.TimeEntered >= dateOffset).OrderBy(x => x.LunchTime).ToList();
ViewBag.positionordered = db.Positions.OrderBy(m => m.PositionName).ToList();
ViewBag.Dths = db.Dths.Where(x => x.TimeEntered <= date && x.TimeEntered >= dateOffset).ToList();
ViewBag.Breaks = db.Breaks.Where(x => x.TimeEntered <= date && x.TimeEntered >= dateOffset).ToList();
ViewBag.Lunches = db.Lunches.Where(x => x.TimeEntered <= date && x.TimeEntered >= dateOffset).ToList();
ViewBag.breakOffFloor = db.Breaks.Where(x => x.EmpSent == true && x.TimeCleared == null && (x.TimeEntered <= date && x.TimeEntered >= dateOffset)).ToList();
ViewBag.dthOffFloor = db.Dths.Where(x => x.EmpSent == true && x.TimeCleared == null && (x.TimeEntered <= date && x.TimeEntered >= dateOffset)).ToList();
ViewBag.lunchOffFloor = db.Lunches.Where(x => x.EmpSent == true && x.TimeCleared == null && (x.TimeEntered <= date && x.TimeEntered >= dateOffset)).ToList();
string partialHtml = Common.RenderRazorViewToString(ControllerContext,"~/Views/Home/_DropDowns.cshtml");
return Json(new { success = true,html = partialHtml },JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
return Json(new { success = false });
}
}
索引:
var employee = ViewBag.EmployeesNames;
var positionNames = ViewBag.PositionNames;
var modelOrdered = ViewBag.LunchTimes;
var positionordered = ViewBag.positionordered;
var breakOffFloor = ViewBag.breakOffFloor;
var dthOffFloor = ViewBag.dthOffFloor;
var lunchOffFloor = ViewBag.lunchOffFloor;
<div class="card" id="Dropdowns" style="width: 12.5em; margin-left: .5em; position:absolute">
<div class="card-body" id="refresh-card" style="margin-right:3em; margin-left:-.5em">
<h5 class="card-title " style="text-align:center; display:inline-block; margin-left:3em">DTH <img src="~/Content/Images/question.jpg" height="15" width="15"
data-toggle="popover" title="@DTHquestion"/></h5>
<table class="table-bordered" style="width:10em;">
@*populate the table with only those breaks that lack a TimeCleared value*@
@if (ViewBag.Dths != null)
{
foreach (var item in ViewBag.Dths)
{
if (item.TimeCleared == null)
{
if (item.TimeEntered.AddMinutes(1) > DateTime.Now)
{
if (item.EmpSent == false)
{
<tr>
@*Make each name clickable to set a TimeCleared datetime.Now time*@
<td class="listTime">
<input type="hidden" class="hiddenDthID" value="@item.DthID" />
<a href="Javascript:;" class="empNameDth" style="color:black">@item.Employee.displayName</a>
</td>
<td class="listTime" style="width:2.5em">
@item.Position.PositionName
</td>
<td class="listTime" style="width:1.5em; text-align:center">
<input type="checkBox" class="dthSent" value="@item.EmpSent" />
</td>
</tr>
}
if (item.EmpSent == true)
{
<tr>
@*Make each name clickable to set a TimeCleared datetime.Now time*@
<td class="empSentGreen">
<input type="hidden" class="hiddenDthID" value="@item.DthID" />
<a href="Javascript:;" class="empNameDth" style="color:black">@item.Employee.displayName</a>
</td>
<td class="empSentGreen" style="width:2.5em">
@item.Position.PositionName
</td>
<td class="empSentGreen" style="width:1.5em; text-align:center">
<img height="13" width="13" src="~/Content/Images/disabledcheck.jpg" />
</td>
</tr>
}
}
else
{
if (item.EmpSent == false)
{
<tr>
@*Make each name clickable to set a TimeCleared datetime.Now time*@
<td class="DthIdNumber">
<input type="hidden" class="hiddenDthID" value="@item.DthID" />
<a href="Javascript:;" class="empNameDth" style="color:black">@item.Employee.displayName</a>
</td>
<td class="DthIdNumber" style="width:2.5em">
@item.Position.PositionName
</td>
<td class="DthIdNumber" style="width:1.5em; text-align:center">
<input type="checkBox" class="dthSent" value="@item.EmpSent" />
</td>
</tr>
}
if (item.EmpSent == true)
{
<tr>
@*Make each name clickable to set a TimeCleared datetime.Now time*@
<td class="DthIdNumber" style="background-color:lightgreen">
<input type="hidden" class="hiddenDthID" value="@item.DthID" />
<a href="Javascript:;" class="empNameDth" style="color:black">@item.Employee.displayName</a>
</td>
<td class="DthIdNumber" style="width:2.5em;background-color:lightgreen">
@item.Position.PositionName
</td>
<td class="DthIdNumber" style="width:1.5em; background-color:lightgreen;text-align:center">
<img height="13" width="13" src="~/Content/Images/disabledcheck.jpg" />
</td>
</tr>
}
}
}
}
}
</table>
谢谢!
解决方法
是的,您共享的代码中存在优化范围。但这无法解决您的潜在问题。 真正的问题不是代码,而是糟糕的数据库设计和解决问题的方法。
我建议您只保留一张桌子供午餐使用。说(LUNCH_DETAILS)
基于上述共同问题,结构看起来像这样:
ID (Primary Key) PostionId EmployeeId TimeEntered TimeCleares IsAvailable ...others
101 10 1001 12:30 01:00 Y .........
102 11 1002 12:40 N .........
现在任何时候任何员工访问食堂吃午餐时,您都只需要在上表中插入一个即可,并根据IsAvailable
列可以判断当前是否有某个职位(带有PostionId
)是否可用。
采用这种方法,将只有一个插入操作,而无需迭代任何数据。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。