Linq Projection неправильно кэшируется в NHibernate 3.2 - PullRequest
6 голосов
/ 06 января 2012

Учитывая простую проекцию, подобную приведенной ниже, NHibernate будет кэшировать план запроса и не обновлять значение переменной, когда запрос такой же:

    int argValue = 1;
    var result1 = database.Users.Select(x => new {x.Name, BadArg = argValue}).First();

    argValue = 2;
    var result2 = database.Users.Select(x => new {x.Name, BadArg = argValue}).First();

Ожидается

значение result1 будет равно Name = "Bob" и BadArg = 1

значение result2 будет равно Name = "Bob" и BadArg = 2

Actual

значение result1 будет равно Name = "Bob" и BadArg = 1

значение result2 будет равно Name = "Bob" и BadArg = 1

Очевидноэто может вызвать много сумасшедшего поведения, если вы этого не ожидаете.Я видел пару сообщений об ошибках , похожих на это в отслеживании ошибок NHibernate, но с мая этого года не было никаких действий над ним.Таким образом, либо никто не использует Linq для Nhibernate слишком много, либо есть какой-то обходной путь, о котором я не знаю.

Прежде чем копаться в источнике NHibernate, есть способ отключить кэширование плана запросов, чтобы предотвратить это поведениеили какой-то другой обходной путь, или кто-нибудь применил патч по вышеуказанной ссылке?

Примечание

Этот пример предназначен для упрощения вопроса, на самом деле у меня сложный вопрос.проекция, которую я хочу сохранить как IQueryable, преждевременное преобразование в IEnumerable не будет работать.

Обновление Не работает в мастере github для Nhibernate 3.2.1

Ответы [ 2 ]

0 голосов
/ 06 января 2012

Вот как отключить кэш первого уровня: http://darioquintana.com.ar/blogging/2007/10/08/statelesssession-nhibernate-without-first-level-cache/

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

(По сути, вам нужно создавать и уничтожать сеансы для каждого запроса.)

Если вы обнаружите, что проблема все еще сохраняется, вам придется сделать то, что предложил Ритмис.

0 голосов
/ 06 января 2012

Если вы хотите полностью избежать кэширования, попробуйте изменить код следующим образом:

int argValue = 1;
var result1 = database.Users.AsEnumerable().Select(x => new {x.Name, BadArg = argValue}).First();

argValue = 2;
var result2 = database.Users.AsEnumerable().Select(x => new {x.Name, BadArg = argValue}).First();

В результате получается, что вместо использования метода NHLinq Select вы в конечном итоге будете использовать System.Linq Select.метод - эффективное предотвращение кэширования проекции NHibernate.Конечно, недостатком является то, что вы будете выполнять проекцию в памяти, поэтому вы в конечном итоге выберете все поля из своей таблицы пользователей, а не только те, которые вы хотите.

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