Добавление кэширования перед подсчетом приведет к кэшированию итоговых результатов подсчета. Это видно из SQL, созданного в моем примере ниже.
домена и картографии Код
public class Entity
{
public virtual long id { get; set; }
public virtual string name { get; set; }
}
public class EntityMap : ClassMap<Entity>
{
public EntityMap()
{
Id(x => x.id).GeneratedBy.Identity();
Map(x => x.name);
Cache.ReadOnly();
}
}
сам тестовый код.
using (var session = NHibernateHelper.OpenSession())
using (var tx = session.BeginTransaction())
{
session.Save(new Entity() { name = "Smith" });
session.Save(new Entity() { name = "Smithers" });
session.Save(new Entity() { name = "Smithery" });
session.Save(new Entity() { name = "Smith" });
tx.Commit();
}
String name_constant = "Smith";
using (var session = NHibernateHelper.OpenSession())
using (var tx = session.BeginTransaction())
{
var result = session.Query<Entity>().Cacheable().Count(e => e.name == name_constant);
}
using (var session = NHibernateHelper.OpenSession())
using (var tx = session.BeginTransaction())
{
var result = session.Query<Entity>().Cacheable().Count(e => e.name == name_constant);
}
SQL, полученный из приведенного выше кода, приведен ниже. Как вы можете видеть, есть четыре оператора INSERT
, по одному для каждого session.Save
. В то время как существует только один SELECT
, несмотря на два запроса, каждый из которых выполняет отдельную сессию. Это связано с тем, что результат был сфотографирован NHibernate.
NHibernate: INSERT INTO [Entity] (name) VALUES (@p0); select SCOPE_IDENTITY();
@p0 = 'Smith' [Type: String (4000)]
NHibernate: INSERT INTO [Entity] (name) VALUES (@p0); select SCOPE_IDENTITY();
@p0 = 'Smithers' [Type: String (4000)]
NHibernate: INSERT INTO [Entity] (name) VALUES (@p0); select SCOPE_IDENTITY();
@p0 = 'Smithery' [Type: String (4000)]
NHibernate: INSERT INTO [Entity] (name) VALUES (@p0); select SCOPE_IDENTITY();
@p0 = 'Smith' [Type: String (4000)]
NHibernate: select cast(count(*) as INT) as col_0_0_ from [Entity] entity0_
where [email protected];
@p0 = 'Smith' [Type: String (4000)]
Возможные сценарии, которые будут вызывать NHibernate игнорировать Cacheable
и вернуться к БД, когда:
- Второй тайник уровня не включен в конфигурации сеанса фабрики.
- Объект не был помечен как кешируемый.
Единственный сценарий, я знаю, что приведет к NHibernate для выполнения двух SELECT
запросов является случаем, когда объект был выселен из кэша, либо явно с помощью sessionFactory.Evict
или кэшированный объект становится истек между двумя вызовами.
Посмотрите на метод FromCache() LINQ. –
Где именно должен находиться этот метод? –
Хммм, возможно, вы можете сделать что-то вроде '.Where (e => e.Property == someConstant) .Cacheable(). ToList()', а затем просто используйте свойство .Count' в списке. Или вы конкретно пытаетесь избежать кэширования списка сущностей? – Alden