Улучшение foreach List и сохранение большего количества данных в базе данных - PullRequest
0 голосов
/ 27 февраля 2020

Я создаю код для сохранения дополнительных данных в базе данных SQL, используя Entity Framework 5.0

Я строю этот код:

                foreach (EcgDTO.HrvData data in u.hrvData)
                {
                    if (data.hrv != null && data.hrv.Count > 0)
                    {

                        foreach (String d in data.hrv)
                        {
                            ECG ecg = new ECG();
                            ecg.Id = id++;
                            ecg.IdPerson = idPatient;
                            ecg.y = Decimal.Parse(d);
                            ecg.timestamp = data.createdDate;
                            dbData.ECG.Add(ecg);
                        }

                    }
                }
                int savedData = dbData.SaveChanges();

Это класс ЭКГ

 [DataContract]
    public class EcgDTO
    {

        [DataMember(Name = "hrvData")]
        public List<HrvData> hrvData { get; set; }



        public class HrvData
        {
            [DataMember(Name = "patientId")]
            public String patientId { get; set; }
            [DataMember(Name = "hrv")]
            public List<String> hrv { get; set; }
            [DataMember(Name = "createdDate")]
            public DateTime createdDate { get; set; }
            [DataMember(Name = "createdBy")]
            public String createdBy { get; set; }
            [DataMember(Name = "modifiedBy")]
            public String modifiedBy { get; set; }

            [DataMember(Name = "modifiedDate")]
            public DateTime modifiedDate { get; set; }


        }
    }

Теперь мой входной список может содержать 227 элементов, а список HRV содержит 67 значений

Есть ли способ повысить скорость прокрутки двух списков и сохранения в базе данных?

1 Ответ

1 голос
/ 28 февраля 2020

При вставке большого количества строк фактором производительности является DbContext и его кеш отслеживания. Чем больше сущностей отслеживает DbContext, тем больше времени потребуется для принятия изменений и попыток просмотра и обновления всех связей. Для различных больших наборов (10 тысяч или более) вы должны разделить наборы на более управляемые блоки. В вашем случае это может быть необязательным, но я бы проверил, что ваш DbContext максимально короткий, чтобы избежать работы со всеми другими отслеживаемыми объектами при выполнении этой операции. Для начала:

using(var insertContext = new MyAppContext())
{
    foreach (EcgDTO.HrvData data in u.hrvData)
    {
        if (data.hrv == null && data.hrv.Count == 0)
            continue;

        foreach (String d in data.hrv)
        {
            ECG ecg = new ECG
            {
                Id = id++;
                IdPerson = idPatient;
                y = Decimal.Parse(d);
                timestamp = data.createdDate;
            };
            insertContext.ECG.Add(ecg);
        }
    }
    int savedData = insertContext.SaveChanges();
}

Вы можете построить объекты ЭКГ, используя Linq, но я не думаю, что это было бы так легко понять. Ключевое предложение здесь состоит не в том, чтобы использовать основной DbContext, а вместо этого выполнять вставки, используя выделенный экземпляр DbContext, который ограничен только этой операцией.

Logi c подобно Id = id++; вызывает некоторое беспокойство, поскольку для этого потребуется только один экземпляр этой операции для выполнения в любой конкретный момент времени. В идеале присвоение идентификатора для новых строк должно передаваться на уровне БД с использованием столбцов Identity или методов Sequence / generation, где EF настроен для обработки их как столбцов Identity. Таким образом, вам не нужно беспокоиться о нескольких экземплярах, пытающихся вставить одинаковые диапазоны идентификаторов. Например, если для id установлено что-то вроде SELECT MAX(Id) From ECG, если два экземпляра начнут эту операцию примерно в одно и то же время, оба экземпляра получат одинаковое значение MAX(Id) из базы данных и попытаются вставить одинаковые увеличенные идентификаторы. Все, что сохранено первым, будет успешным, в то время как второе вызовет исключения относительно дублирующих ПК.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...