Entity Framework SaveChanges () первый вызов очень медленный

Я понимаю, что этот вопрос поднимался несколько раз раньше, но я не могу найти однозначного ответа (возможно, его нет!).

Во всяком случае, название действительно все говорит. Создайте новый контекст, добавьте новую сущность, SaveChanges () займет 20 секунд. Добавьте вторую сущность в том же контексте, SaveChanges () мгновенно.

Есть мысли по этому поводу? :-)

============ ОБНОВЛЕНИЕ =============

Я создал очень простое приложение, работающее с моей существующей моделью, чтобы показать проблему ...

    public void Go()
    {
        ModelContainer context = new ModelContainer(DbHelper.GenerateConnectionString());

        for (int i = 1; i <= 5; i++)
        {
            DateTime start = DateTime.Now;
            Order order = context.Orders.Single(c => c.Reference == "AA05056");
            DateTime end = DateTime.Now;
            double millisecs = (end - start).TotalMilliseconds;
            Console.WriteLine("Query " + i + " = " + millisecs + "ms (" + millisecs / 1000 + "s)");

            start = DateTime.Now;
            order.Note = start.ToLongTimeString();
            context.SaveChanges();
            end = DateTime.Now;
            millisecs = (end - start).TotalMilliseconds;
            Console.WriteLine("SaveChanges " + i + " = " + millisecs + "ms (" + millisecs / 1000 + "s)");

            Thread.Sleep(1000);
        }

        Console.ReadKey();
    }

Пожалуйста, не комментируйте мой код - если это не недействительный тест;)

Результаты следующие:

Запрос 1 = 3999,2288 мс (3,9992288 с)
SaveChanges 1 = 3391,194 мс (3,391194 с)

Запрос 2 = 18,001 мс (0,018001 с)
SaveChanges 2 = 4,0002 мс (0,0040002 с)

Запрос 3 = 14,0008 мс (0,0140008 с)
SaveChanges 3 = 3 0002 мс (0,0030002 с)

Запрос 4 = 13,0008 мс (0,0130008 с)
SaveChanges 4 = 3 0002 мс (0,0030002 с)

Запрос 5 = 10,0005 мс (0,0100005 с)
SaveChanges 5 = 3 0002 мс (0,0030002 с)

Первый запрос требует времени, которое, как я полагаю, является генерацией представления? Или подключение к БД?

Первое сохранение занимает почти 4 секунды, что для более сложного сохранения в моем приложении занимает более 20 секунд, что неприемлемо.

Не уверен, что теперь с этим делать :-(

ОБНОВИТЬ...

SQL Profiler показывает, что первый запрос и обновление выполняются быстро и не отличаются от первого. Итак, я знаю, что задержка - это подозрение на Entity Framework.


person Mark Chidlow    schedule 20.06.2011    source источник
comment
Насколько велика ваша модель? Это первая операция, которую вы выполняете со своим контекстом (также учитываются запросы)?   -  person Ladislav Mrnka    schedule 20.06.2011
comment
@ Стивен - не понимаю, о чем ты. Можете ли вы расшириться? @Ladislav - это первая функция SaveChanges (), но есть предыдущие запросы в том же контексте. Я сохраняю относительно сложный Заказ, где в системе более 10 000 заказов. Это не самый простой проект для отладки, поэтому, вероятно, мы соберем образец приложения для облегчения отладки. Я удалил исправления (временно), и это устраняет ряд проблем с производительностью, но не повлияло на время сохранения. Я пробовал предварительно сгенерировать просмотры, но, похоже, это мало / не имеет никакого эффекта.   -  person Mark Chidlow    schedule 20.06.2011
comment
Хотя порядок довольно сложен (18 FK и т. Д.), Вторая функция SaveChanges () для копии того же порядка выполняется практически мгновенно - если в том же контексте.   -  person Mark Chidlow    schedule 20.06.2011
comment
Я хотел уточнить - в модели около 150 сущностей.   -  person Mark Chidlow    schedule 20.06.2011
comment
Здесь также может происходить некоторая JIT. Вы меняете код / ​​перекомпилируете между тестовыми запусками?   -  person Justin Morgan    schedule 20.06.2011
comment
@ Джастин. Хорошая мысль, но я только что запустил тесты без перекомпиляции и не вижу разницы. Я думал, что мне стоит взглянуть на профилировщик SQL, чтобы узнать, сколько времени занимает обновление. Я взгляну.   -  person Mark Chidlow    schedule 20.06.2011


Ответы (2)


Возможно, это не вызов SaveChanges - при первом обращении к базе данных в EF он должен выполнить некоторую начальную генерацию кода из метаданных. Вы можете предварительно сгенерировать это во время компиляции: http://msdn.microsoft.com/en-us/library/bb896240.aspx

Я был бы удивлен, если бы это была единственная проблема, но это может помочь.

Также посмотрите здесь: http://msdn.microsoft.com/en-us/library/cc853327.aspx

person Isaac Abraham    schedule 20.06.2011

Я бы запустил следующий код при запуске приложения и посмотрел, сколько времени это займет, и если после этого первые SaveChanges будут быстрыми.

    public static void UpdateDatabase()
    {
        //Note: Using SetInitializer is reconnended by Ladislav Mrnka with reputation 275k
        //http://stackoverflow.com/questions/9281423/entity-framework-4-3-run-migrations-at-application-start
        Database.SetInitializer<DAL.MyDbContext>(
            new MigrateDatabaseToLatestVersion<DAL.MyDbContext,
            Migrations.MyDbContext.Configuration>());

        using (var db = new DAL.MyDbContext()) { 
            db.Database.Initialize(false);//Execute the migrations now, not at the first access
        }
    }
person tymtam    schedule 07.11.2016