2010-08-19 14 views

Respuesta

9

siempre se puede hacer un recuento.

que tienden a utilizar DetachedCriteria, así que me gustaría tener algo como:

var criteria = // some criteria that will identify your object 

var result = criteria 
    .GetExecutableCriteria(Session) 
    .SetProjection(Projections.RowCountInt64()) 
    .UniqueResult(); 

return result > 0; 
3

Creo que busca este ...

var fooExists = session.Query<Foo>().Any(f => /*condition*/); 
+0

Esto debería ser var fooExists = session.Query (). Cualquier condición (f =>/* * /) Donde es redundante. Esta es una mala idea porque cualquiera devolverá todas las columnas (entidad completa). –

+0

@DariusKucinskas que no es correcto. Ambas construcciones dan como resultado el MISMO EXACTO SQL. Usar 'Any (x)' en lugar de 'Where (x) .Any()' es un poco más limpio. –

+0

Cualquiera es malo porque recupera la base de datos de formularios de entidad, el recuento de filas es mejor en esta situación. –

2
var exists = 1 == session.CreateQuery("select 1 from MyEntity where Property = :value") 
    .SetValue("value", xxx) 
    .UniqueResult<Int32?>(); 
28

Se puede usar uno de los siguientes 3 preguntas (o puede utilizar los criterios del API Projections.RowCountInt64() desde David responde):

bool exist = session.Query<Employee>() 
    .Any(x => x.EmployeeID == 1); 

bool exist = session.QueryOver<Employee>() 
    .Where(x => x.EmployeeID == 1) 
    .RowCount() > 0; 

bool exist = session.Query<Employee>() 
    .Count(x => x.EmployeeID == 1) > 0; 

Ten en cuenta que Cualquiera es el peor de esos tres porque atrapa a la entidad. A continuación se consulta SQL generada para cada uno:

exec sp_executesql N'select TOP (1) employee0_.EmployeeID as EmployeeID0_, employee0_.Name as Name0_ from Employee employee0_ where [email protected]',N'@p0 int',@p0=1 

exec sp_executesql N'SELECT count(*) as y0_ FROM Employee this_ WHERE this_.EmployeeID = @p0',N'@p0 int',@p0=1 

exec sp_executesql N'select cast(count(*) as INT) as col_0_0_ from Employee employee0_ where [email protected]',N'@p0 int',@p0=1 
+9

OTOH, Cualquiera puede ser el mejor desde una perspectiva de rendimiento: "conteo" puede ser una función de servicio pesado para llamar, dependiendo de volúmenes de datos, índices y similares. Un TOP (1) solo buscará el índice apropiado. ¿Hay un equivalente a 'SELECT TOP (1) 1 FROM table WHERE ...' que sería lo mejor de nuevo (ya que en realidad no extraería ningún dato de la tabla). –

+1

+1 para el desglose detallado. – JasonCoder

+0

Consulte mi respuesta para una consulta que no capta la entidad ni usa el conteo. http://stackoverflow.com/a/24083783/12752 –

5

Para ampliar excelente respuesta Darío Kucinskas', puede evitar ir a buscar la entidad que utiliza Seleccionar:

bool exist = session.Query<Employee>() 
        .Where(x => x.EmployeeID == 1) 
        .Select(x => x.EmployeeID) 
        .Any(); 

Como se ha mencionado, el rendimiento de las consultas debería ser el mismo sin embargo, espero que esto reduzca el tráfico de la red.

0

Según la respuesta Ricardo, esta parece ser la forma más eficaz de comprobar si existe un objeto utilizando HQL.No cuenta y no se carga innecesariamente el objeto:

var exists = session 
    .CreateQuery("select 1 from Widget where _color = 'green'") 
    .SetMaxResults(1) 
    .UniqueResult<Int32?>() 
    .HasValue; 

que genera este SQL (tenga en cuenta que este es SQLite, lo que se limitan en lugar de arriba)

select 
    1 as col_0_0_ 
from 
    Widgets 
where 
    Color='green' limit 1; 
0

Usted puede tener una oportunidad :

public virtual T FindById<T>(int id) 
{ 
    return session.Get(typeof(T), id)); 
} 
8

Así me dejo hacer algunas pruebas con sus ejemplos @Jamie Ide @Darius Kucinskas @Dmitry

enter image description here

Así:

var exists = session 
.CreateQuery("select 1 from Widget where _color = 'green'") 
.SetMaxResults(1) 
.UniqueResult<Int32?>() 
.HasValue; 

en mi caso fue 18% más rápido que

bool exist = session.Query<Employee>() 
    .Any(x => x.EmployeeID == 1); 

14% de

bool exist = session.Query<Employee>() 
    .Count(x => x.EmployeeID == 1) > 0; 

y 8%

bool exist = session.QueryOver<Employee>() 
    .Where(x => x.EmployeeID == 1) 
    .RowCount() > 0; 

Así que en mi opinión, incluso si la consulta no modificable es más rápido el

bool exist = session.QueryOver<Employee>() 
    .Where(x => x.EmployeeID == 1) 
    .RowCount() > 0; 

es la mejor opción debido a buenos hábitos y el código de claridad

Cuestiones relacionadas