Назначение объекта внутри foreach с использованием Entity Framework очень медленное - PullRequest
0 голосов
/ 28 июня 2018

У меня проблема с назначением объекта внутри цикла foreach с использованием Entity Framework, я не знаю, почему это занимает очень много времени (почти 48 секунд для 1800 элементов в цикле !!).

Пример кода:

using (var db = new MyEntities())
{
     foreach (long r in Recipients) //Recipients has 1800 items.
     {
         var temp = new DirectMessage();
         temp = db.DirectMessages().FirstOrDefault();
         temp.SenderProfileImageUrl = "https://www.google.com.sa/images/branding/googlelogo/2x/googlelogo_color_120x44dp.png";    
     }
}

Этот простой цикл занимает около 45 секунд !!

При тестировании и отладке я заметил, что эта команда temp = db.DirectMessages().FirstOrDefault(); делает задержку!

Кроме того, изначально он имел .Where и .OrderBy с использованием r.ID, но я изменил его на самый простой способ, чтобы убедиться, что задержка не из-за фильтрации.

Обновление, оригинальный код:

foreach (long r in Recipients)
                {
                    MsgObj = new AllMsgsClass();

                    MsgObj.LastMsg = db.DirectMessages.Where(a => (a.SenderID == r || a.RecipientID == r)).OrderByDescending(a => a.CreatedDate).AsNoTracking().FirstOrDefault();

                    try
                    {
                        if (MsgObj.LastMsg.MsgSort == "Sent")
                            MsgObj.LastMsg.RecipientProfileImageUrl = "https://avatars.io/twitter/" + MsgObj.LastMsg.RecipientScreenName + "/small";

                        else
                            MsgObj.LastMsg.SenderProfileImageUrl = "https://avatars.io/twitter/" + MsgObj.LastMsg.SenderScreenName + "/small";
                    }
                    catch (Exception dd)
                    {
                        string x = dd.Message;
                    }

                    MsgObj.SortOrder = Convert.ToDateTime(MsgObj.LastMsg.CreatedDate);
                    AllMSGsList.Add(MsgObj);
                }

Любая помощь будет так цениться!

Ответы [ 2 ]

0 голосов
/ 28 июня 2018

Как только я столкнулся с подобной проблемой и выполнил следующие шаги, я надеюсь, что это поможет вам. Это также поможет генерировать EDMX быстрее. Установка уровня совместимости базы данных на 110 сработала для меня. Чтобы проверить уровень совместимости, запустите этот скрипт:

select compatibility_level from sys.databases where name = 'YOUR_DB_NAME'

Чтобы установить уровень совместимости, используйте этот скрипт:

alter database YOUR_DB_NAME set compatibility_level = 110
0 голосов
/ 28 июня 2018

Если db.DirectMessages().FirstOrDefault() вызывает базу данных в каждой итерации, это займет время. Почему бы не использовать это вместо:

using (var db = new MyEntities())
{
     var directMessage = db.DirectMessages().FirstOrDefault();
     foreach (long r in Recipients) //Recipients has 1800 items.
     {
         var temp = new DirectMessage();
         temp = directMessage;
         temp.SenderProfileImageUrl = "https://www.google.com.sa/images/branding/googlelogo/2x/googlelogo_color_120x44dp.png";    
     }
}

Обновленный ответ:

var directMessages = db.DirectMessages.ToList();

foreach (long r in Recipients)
                {
                    MsgObj = new AllMsgsClass();

                    MsgObj.LastMsg = directMessages.Where(a => (a.SenderID == r || a.RecipientID == r)).OrderByDescending(a => a.CreatedDate).AsNoTracking().FirstOrDefault();

                    try
                    {
                        if (MsgObj.LastMsg.MsgSort == "Sent")
                            MsgObj.LastMsg.RecipientProfileImageUrl = "https://avatars.io/twitter/" + MsgObj.LastMsg.RecipientScreenName + "/small";

                        else
                            MsgObj.LastMsg.SenderProfileImageUrl = "https://avatars.io/twitter/" + MsgObj.LastMsg.SenderScreenName + "/small";
                    }
                    catch (Exception dd)
                    {
                        string x = dd.Message;
                    }

                    MsgObj.SortOrder = Convert.ToDateTime(MsgObj.LastMsg.CreatedDate);
                    AllMSGsList.Add(MsgObj);
                }
...