#c# #sql #asp.net-mvc #loops
#c# #sql #asp.net-mvc #циклы
Вопрос:
Я совершенно новый программист и застрял — надеюсь на совет.
У меня есть программа через ASP.net . Это отлично работает, пока в БД не будет около 100 записей, а затем она становится действительно медленной.
Я знаю причину, но не знаю, как это исправить.
Программа позволяет сотрудникам крупного диспетчерского центра 911 подписываться на перерывы, обеды и перерывы в туалет со своих консолей. Они выбирают свои имена и позиции из выпадающих списков. Он добавляет информацию в БД, когда они нажимают кнопку отправки. Затем программа выполняет итерацию по БД, чтобы найти активные перерывы / обеды / перерывы в туалет, чтобы найти активные и отображает их в таблице.
Важно, чтобы таблица быстро обновлялась, когда кто-то переходит в список, чтобы все со всех консолей знали, когда кто-то добавляет в эту таблицу. Итак, у меня есть программа, которая перебирает БД каждые 5 секунд, чтобы обновить, кто в каком списке. Он доволен менее чем 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 amp;amp; 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 amp;amp; x.TimeEntered >= dateOffset).ToList();
ViewBag.Breaks = db.Breaks.Where(x => x.TimeEntered <= date amp;amp; x.TimeEntered >= dateOffset).ToList();
ViewBag.Lunches = db.Lunches.Where(x => x.TimeEntered <= date amp;amp; x.TimeEntered >= dateOffset).ToList();
ViewBag.breakOffFloor = db.Breaks.Where(x => x.EmpSent == true amp;amp; x.TimeCleared == null amp;amp; (x.TimeEntered <= date amp;amp; x.TimeEntered >= dateOffset)).ToList();
ViewBag.dthOffFloor = db.Dths.Where(x => x.EmpSent == true amp;amp; x.TimeCleared == null amp;amp; (x.TimeEntered <= date amp;amp; x.TimeEntered >= dateOffset)).ToList();
ViewBag.lunchOffFloor = db.Lunches.Where(x => x.EmpSent == true amp;amp; x.TimeCleared == null amp;amp; (x.TimeEntered <= date amp;amp; 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>
Спасибо!
Ответ №1:
Да, в коде, которым вы делитесь, есть область оптимизации. Но это не решит вашу основную проблему. Реальная проблема заключается не в коде, а в плохом дизайне базы данных и плохом подходе к проблеме.
Я бы посоветовал вам сохранить только одну таблицу для деталей обеда. скажем (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
столбца вы можете определить, доступна ли позиция (with PostionId
) в данный момент или нет.
При таком подходе будет только одна операция вставки, и не нужно будет выполнять итерацию по каким-либо данным.
Комментарии:
1. Спасибо! Я думаю, что мы на одной странице, но я не думаю, что хорошо объяснил себя. За обед обновляется одна запись. Когда создается lunch, обновляется одна запись. Время, указанное при создании, помечается. Когда они уходят на обед, EmpSent bool устанавливает значение true . Когда они возвращаются, время очистки помечается — все в одной записи. Я прикрепил картинку, чтобы вы могли видеть, как выглядит моя таблица. Проблема на следующем рисунке. Чтобы заполнить эту таблицу в пользовательском интерфейсе, я выполняю итерацию. Если TimeEntered != null но TimeCleared == null, покажите это. Если значение True, зеленый и т. Д. Эта итерация — мое узкое место.