Да - возьмите копию переменной внутри цикла:
while (variable < 5)
{
int copy = variable;
actions.Add(() => copy * 2);
++ variable;
}
Вы можете думать об этом, как если бы компилятор C # создавал «новую» локальную переменную каждый раз, когда он попадает в объявление переменной. На самом деле он создаст соответствующие новые объекты закрытия, и он становится сложным (с точки зрения реализации), если вы ссылаетесь на переменные в нескольких областях, но он работает:)
Обратите внимание, что более распространенное появление этого проблема заключается в использовании for
или foreach
:
for (int i=0; i < 10; i++) // Just one variable
foreach (string x in foo) // And again, despite how it reads out loud
Подробнее об этом см. в разделе 7.14.4.2 спецификации C # 3.0, а моя статья о замыканиях еще несколько примеров.
Одним из первых шагов, которые вы можете предпринять для решения этой проблемы, является сбор дополнительной информации путем установки «hibernate.show_sql» в «true» в ваших конфигурационных файлах, чтобы точно увидеть, что именно генерируется SQL. Это позволит вам увидеть и протестировать сгенерированные запросы, чтобы изолировать источник проблемы.
Мое лучшее предположение без дополнительной информации состоит в том, что это утверждение вызывает нетерпеливое извлечение для большого количества записей. Чрезмерное изнашивание выборки - распространенная ошибка, которая может значительно замедлить применение Hibernate. Желающий выбор Hibernate может быть очень неэффективным, извлекать записи по одному и запускать большое количество запросов к базе данных.