2011-01-20 15 views
5

Estoy usando NHibernate y tengo problemas con esta consulta ... Tengo un elemento de clase que quiero buscar con su Id. Todo muy bien. Sin embargo, también quiero que una propiedad bool en la clase Item se establezca en verdadero si se establece alguna otra condición. Específicamente, esta propiedad se denomina IsMarked, indicando si el artículo está marcado/fijo/marcado para el usuario que lo solicitó, y esta información se establece en una tabla que proporciona la relación entre el artículo y el usuario.Valor de configuración basado en una tabla diferente en la consulta de NHibernate

Actualmente estoy obteniendo el artículo y luego buscando la referencia, actualizando la propiedad a verdadero si se puede encontrar la referencia. ¿Puedo hacer esto en una consulta en su lugar?

var item = Session.Get<Item>(itemId); 

var flaggedResult = Session.CreateCriteria<ItemWithUserFlag>() 
    .Add(Restrictions.Eq("User.Id", userId)) 
    .Add(Restrictions.Eq("Item", item)) 
    .List<ItemWithUserFlag>(); 

if (flaggedResult.Count > 0) 
    item.IsMarked = true; 

return item; 
+0

¿Cómo se asignan las clases? ¿Hay una repetición de muchos a muchos entre Usuario y Artículo? –

+0

Uso Fluent para las asignaciones. Hay una relación de muchos a muchos representada en una clase separada ItemWithUserFlag. El usuario no tiene una relación directa con el artículo, y el artículo no tiene una relación directa con el usuario. ItemWithUserFlag tiene una Referencias establecida para Usuario y para Artículo. – stiank81

Respuesta

7

Cómo sobre el uso formula junto con filter en su asignación de propiedad:

<property name="IsMarked" formula="(select count(*) from ItemWithUserFlag where ItemWithUserFlag.ItemId = ItemId and ItemWithUserFlag.UserId = :UserFilter.userId)" /> 

y el filtro def:

<filter-def name="UserFilter"> 
    <filter-param name="userId" type="Int32"/> 
</filter-def> 

que resultará en algo así como

SELECT Item.*, (select count(*) from ItemWithUserFlag where ItemWithUserFlag.ItemId = Item.ItemId and ItemWithUserFlag.UserId = ?) AS IsMarked FROM Item 

Siempre que IsMarked se defina como bool, si count(*) devuelve 0, se convertirá en false y en todo caso > 0 se convertirá en true.

EDIT: representación Fluido

public class ItemMap : ClassMap<Item> 
{ 
    public ItemMap() 
    { 
     /// ... whatever 
     Map(x => x.IsMarked).Formula("(select count(*) from ItemWithUserFlag where ItemWithUserFlag.ItemId = ItemId and ItemWithUserFlag.UserId = :UserFilter.userId)"); 
    } 
} 

public class UserFilter : FilterDefinition 
{ 
    public UserFilter() 
    { 
     WithName("UserFilter") 
      .AddParameter("userId", NHibernate.NHibernateUtil.Int32); 
    } 
} 
+0

¡Thx! Todavía no lo he probado, pero parece que esto funcionaría. El problema en mi caso es que utilizo FluentNhibernate para las asignaciones. No sé si puedo definir algunas asignaciones i xml al mismo tiempo, o si lo mismo se puede expresar en Fluent. Entonces, ¿no hay forma de lograr esto directamente en la consulta? – stiank81

+0

@ stiank81 Agregué lo que creo que debería funcionar con Fluent. –

+0

@ stiank81 Acerca de lograr esto en la consulta: creo que no hay forma. Lógicamente, lo que quiere no es una restricción o qué, sino una columna calculada, por lo que creo que debe hacerse a través de asignaciones. Pero no soy tan experto en nHibernate y, por lo tanto, no puedo asegurarlo. –

Cuestiones relacionadas