Используйте только часть БД при итерации ASP.net — итерация по всей базе данных значительно замедляет ее

#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, зеленый и т. Д. Эта итерация — мое узкое место.