Реализации Рамочной сущности вставки с более высокой производительностью


У меня очень медленно выступлений на эф. У меня много по каждому элементу сопоставления.

У вас есть предложения? Я хотел бы сделать благоустройство без сложный рефакторинг, и я хотел бы использовать эф.

  public bool Monitoring(MonitoringInformation monitoringInformation)
        {
            if (null == monitoringInformation) throw new ArgumentNullException(nameof(monitoringInformation));

            bool insertSuccess = false;

            // false is for lazy loading = false
            using (var context = new MonitoringToolContext(false))
            {
                var entity = MonitoringStatuses(monitoringInformation, context);
                context.MonitoringInformation.Add(entity);
                context.Configuration.AutoDetectChangesEnabled = false;
                context.SaveChanges();
                insertSuccess = true;
            }
            return insertSuccess;
        }

        private DataModels.MonitoringInformation MonitoringStatuses(MonitoringInformation monitoringInformation, MonitoringToolContext context)
        {
            var retMi = new DataModels.MonitoringInformation
            {
                InsertedDateTime = monitoringInformation.InsertedDateTime,
                Filename = monitoringInformation.Filename,
                GeneratedDate = monitoringInformation.GeneratedDate,
                Version = monitoringInformation.Version,
                FileType = monitoringInformation.FileType
            };

            retMi.DeviceStatuses = DoDeviceStatus(monitoringInformation.Devices, context);

            retMi.HardwareStatusInformations = DoHardwareComponentStatuses(monitoringInformation.HardwareComponents, monitoringInformation.EODs, context);

            return retMi;
        }

        private ICollection<DataModels.DeviceStatus> DoDeviceStatus(IEnumerable<Device> devices, MonitoringToolContext context)
        {
            var dStatusList = new List<DataModels.DeviceStatus>();

            foreach (var device in devices)
            {
                var tmp = context.Device.FirstOrDefault(x => x.Name == device.Name);
                if (tmp == null) continue;

                dStatusList.Add(new DataModels.DeviceStatus
                {
                    DeviceId = tmp.DeviceId,
                    File = device.DeviceStatus.File,
                    Status = device.DeviceStatus.Status
                });
            }

            return dStatusList;
        }

        private ICollection<DataModels.HardwareStatusInformation> DoHardwareComponentStatuses(IEnumerable<HardwareComponent> hwComponents, List<Eod> eods, MonitoringToolContext context)
        {
            var dHwStatuses = new List<DataModels.HardwareStatusInformation>();

            foreach (var hardwarecomponent in hwComponents)
            {

                var dHwComp = new DataModels.HardwareComponent();
                var dHwStatus = new DataModels.HardwareStatusInformation()
                {
                    HardwareComponent = dHwComp,
                    DiskFree = hardwarecomponent.HardwareStatusInformation.DiskFree,
                    DiskTotal = hardwarecomponent.HardwareStatusInformation.DiskTotal,
                    LastUpdate = hardwarecomponent.HardwareStatusInformation.LastUpdate,
                    RamFree = hardwarecomponent.HardwareStatusInformation.RamFree,
                    RamTotal = hardwarecomponent.HardwareStatusInformation.RamTotal,
                    RamUnit = hardwarecomponent.HardwareStatusInformation.RamUnit,
                    UpTime = hardwarecomponent.HardwareStatusInformation.UpTime,
                    GroupId = hardwarecomponent.GroupId
                };

                foreach (var softwarecomponent in hardwarecomponent.SoftwareComponents)
                {
                    var tmpSwComp = context.SoftwareComponent.FirstOrDefault(x => x.Name == softwarecomponent.Name);
                    if (tmpSwComp == null) continue;

                    dHwStatus.HardwareComponent.SoftwareComponentStatus.Add(new DataModels.SoftwareComponentStatus()
                    {
                        SoftwareComponentId = tmpSwComp.SoftwareComponentId,
                        LastUpdate = softwarecomponent.SoftwareComponentStatus.LastUpdate,
                        Status = softwarecomponent.SoftwareComponentStatus.Status,
                        Version = softwarecomponent.SoftwareComponentStatus.Version,
                    });
                }

                dHwComp.EodStatus = DoEodStatus(eods, context);

                dHwStatuses.Add(dHwStatus);
            }
            return dHwStatuses;
        }

        private ICollection<DataModels.EODStatus> DoEodStatus(IEnumerable<Eod> eods, MonitoringToolContext context)
        {
            var dEodList = new List<DataModels.EODStatus>();

            foreach (var eod in eods)
            {
                var tmpEod = context.EOD.FirstOrDefault(x => x.FileVersion == eod.FileVersion);
                if (tmpEod != null)
                {
                    dEodList.Add(new DataModels.EODStatus()
                    {
                        EodId = tmpEod.EODId,
                        Location = eod.EodStatus.Location,
                        VersionType = eod.EodStatus.VersionType,
                        FileType = eod.EodStatus.FileType,
                        FileVersion = eod.EodStatus.FileVersion,
                        EffectiveDate = eod.EodStatus.EffectiveDate
                    });
                }
            }

            return dEodList;
        }


155
-3
задан 3 апреля 2018 в 08:04 Источник Поделиться
Комментарии
1 ответ

Хотя, безусловно, отсутствие конкретных цифр, тот простой факт, что вы петли через несколько коллекций и сделать FirstOrDefault для каждого элемента является, несомненно, крупным проблему производительности.

Вы должны сделать один запрос и сохранить результаты в Dictionary<T, T>и затем, когда цикл выборки необходимых данных из словаря (используя TryGetValue).

Если бы вы начали сервера SQL профайлер сессии вы, несомненно, видели сотни SELECT запросов; замена тех, с одним можно было бы уже облегчить много нагрузки на сервер.


Теперь несколько советов относительно кода:


  • MonitoringStatuses не правильное имя метода и даже не вернуть то, что вы говорите.

  • DoHardwareComponentStatuses, DoDeviceStatus и DoEodStatus Не отличный способ имена.

  • Проходя вокруг MonitoringToolContext context каждый способ кажется громоздким для меня. Двигаться MonitoringStatuses и его зависимые методы в отдельный класс его собственный-например, MonitoringInformationCreator - и передайте MonitoringToolContext его конструктору, таким образом, сохраняя его на уровне класса.

  • Не бесцельно сокращать: retMi не полезное имя переменной, dHwComp и dHwStatus подавно (что такое "Г" даже в виду?).

  • Пока мы на тему плохие имена переменных: tmp это чрезвычайно плохо. tmpEod не намного лучше.

  • Не используйте такие слова, как "список" в именах переменных, например, dStatusList. Просто использовать во множественном числе то, что коллекция содержит, например, var deviceStatuses = new List<DataModels.DeviceStatus>();.

  • Если у вас есть аббревиатура, которая больше, чем две буквы, напр. EODтогда код C# стиль свод правил говорит использовать PascalCase и таким образом имя его Eod. C# код не должен иметь более трех прописных букв подряд, и даже три подряд-это исключительный случай. Так EODStatus должен быть переименован (вы же применить это правильно при именовании свойств: EodStatus).


Код, кажется, включает копирование содержимого одного объекта в другой. Возможно, используя что-то вроде AutoMapper может сделать это проще для вас?

1
ответ дан 3 апреля 2018 в 12:04 Источник Поделиться