Pregunta

Tengo un "patrimonio" de la entidad, y esta entidad tiene una colección de "EstateFeatures"(tipo:EstateFeature) y EstateFeature tiene una propiedad "MyFeatureValue".

Nota:Estas son las propiedades limitadas por la pregunta.Todas las Entidades tiene un Id y todo es necesario, etc

Estate

IList<EstateFeature> EstateFeatures;

EstateFeature

FeatureValue MyFeatureValue;

FeatureValue

public virtual long Id;

Estoy tratando de conseguir los inmuebles que han dado FeatureValue.Id

DetachedCriteria query = DetachedCriteria.For<Estate>();
Conjunction and = new Conjuction();
foreach (var id in idCollection)
   and.Add(Expression.Eq("MyFeatureValue.Id",id);

query
     .CreateCriteria("EstateFeatures")
     .Add(and);
IList<Estate> estates = query.GetExecutableCriteria(session).List<Estate>();

Nada volvió de esta consulta, estoy haciendo algo mal ?

Gracias

¿Fue útil?

Solución

Usted tendrá que asegurarse de que usted se une a MyFeatureValue una vez para cada una de las características que usted desea que su patrimonio tiene.

Es una manera de llamar .CreateAlias para cada iteración, la dotan de un alias, a continuación, agregar la expresión "aliasX.Id"

foreach (var id in idCollection)
{
   query = query.CreateAlias("MyFeatureValue", "feature" + id)
                .Add(Expression.Eq("feature" + id + ".Id",id);


}

Realidad no recordar cómo la sintaxis va, escribió esta fuera de mi cabeza, no se si usted necesita para volver a declarar consulta :)

Sin embargo, creo que esto va a empezar.

EDITAR:Ya que un error en la API de Criterios de restricción para que usted asociando una colección de varias veces el uso de CreateAlias o CreateCriteria, deberá recurrir a HQL.

http://derek-says.blogspot.com/2008/06/duplicate-association-path-bug-in.html

(Hibernate sufre el mismo problema así)

select e   
FROM Estate AS e
INNER JOIN e.MyFeatureValue AS fv1
INNER JOIN e.MyFeatureValue AS fv2
WHERE fv1.Id = 3
   AND fv2.Id = 13

que se necesita para construir el HQL de forma dinámica, de modo que su alias se convierte en única (fv1, fv2, fvX ...)

Otros consejos

Si he entendido bien creo que algo como esto podría funcionar

CreateCriteria(typeof(Estate))
     .CreateAlias("EstateFeatures", "estatefeature")
     .Add(Restrictions.In("estatefeature.MyFeatureValue.Id", ids))
     .List<Estate>();

¿Qué consulta generó NHibernate para usted? Esto se puede comprobar mediante el uso de la propiedad de configuración show_sql.

A mi consulta, que está tratando de obtener todos los estados que tienen un determinado conjunto de características. Pienso, esto generará una consulta que se parece a

SELECT ....
FROM Estates
INNER JOIN Features
WHERE Feature.Id = 1 AND Feature.Id = 2 ...

Si desea recuperar todos los polígonos que contienen todas las características especificadas, creo que tendrá que usar una disyunción, de manera que NHibernate recupera todos los estados que tienen al menos una de esas características. Luego, en su cliente de código, tendrá que inspeccionar todos los inmuebles en su 'código de cliente', por lo que finalmente acaba de terminar con Estates que tiene todas las características.
No sé si hay una manera más eficiente de dejar que NHibernate manejar esto ...

El código es el que está de paso en una lista de FeaturesValueIds y desea una lista que tiene todas esas características. Si ese es el caso, me gustaría tener una mirada en el SQL que se está generando, y ejecutarlo contra la base de datos para ver si debe volver a estar nada.

De lo contrario, si usted está buscando una lista que tiene cualquiera de las características que está pasando en, usted debe usar una disyunción en lugar de una conjunción.

    exec sp_executesql N'SELECT TOP 3 id11_1_, Address11_1_, Title11_1_, Descript4_11_1_, 
    Price11_1_, Discount11_1_, ForBankL7_11_1_, AddDate11_1_, LastUpdate11_1_, 
IsVisible11_1_, ViewCount11_1_, SaleOrRent11_1_, LocationId11_1_, StaffId11_1_, 
CategoryId11_1_, id27_0_, EstateId27_0_, FeatureV3_27_0_ FROM (SELECT ROW_NUMBER() 
OVER(ORDER BY __hibernate_sort_expr_0__) as row, query.id11_1_, query.Address11_1_, 
query.Title11_1_, query.Descript4_11_1_, query.Price11_1_, query.Discount11_1_, 
query.ForBankL7_11_1_, query.AddDate11_1_, query.LastUpdate11_1_, query.IsVisible11_1_, 
query.ViewCount11_1_, query.SaleOrRent11_1_, query.LocationId11_1_, query.StaffId11_1_, 
query.CategoryId11_1_, query.id27_0_, query.EstateId27_0_, query.FeatureV3_27_0_, 
query.__hibernate_sort_expr_0__ FROM (SELECT this_.id as id11_1_, this_.Address as 
Address11_1_, this_.Title as Title11_1_, this_.Description as Descript4_11_1_, this_.Price 
as Price11_1_, this_.Discount as Discount11_1_, this_.ForBankLoan as ForBankL7_11_1_, 
this_.AddDate as AddDate11_1_, this_.LastUpdate as LastUpdate11_1_, this_.IsVisible as 
IsVisible11_1_, this_.ViewCount as ViewCount11_1_, this_.SaleOrRent as SaleOrRent11_1_, 
this_.LocationId as LocationId11_1_, this_.StaffId as StaffId11_1_, this_.CategoryId as 
CategoryId11_1_, estatefeat1_.id as id27_0_, estatefeat1_.EstateId as EstateId27_0_, 
estatefeat1_.FeatureValueId as FeatureV3_27_0_, CURRENT_TIMESTAMP as 
__hibernate_sort_expr_0__ FROM Estate this_ inner join EstateFeature estatefeat1_ on 
this_.id=estatefeat1_.EstateId WHERE this_.CategoryId = @p0 and 
(estatefeat1_.FeatureValueId = @p1 and estatefeat1_.FeatureValueId = @p2 and 
estatefeat1_.FeatureValueId = @p3 and estatefeat1_.FeatureValueId = @p4 and 
estatefeat1_.FeatureValueId = @p5 and estatefeat1_.FeatureValueId = @p6 and 
estatefeat1_.FeatureValueId = @p7)) query ) page WHERE page.row > 0 ORDER BY 
__hibernate_sort_expr_0__',N'@p0 bigint,@p1 bigint,@p2 bigint,@p3 bigint,@p4 bigint,@p5 
bigint,@p6 bigint,@p7 bigint',@p0=3,@p1=7,@p2=8,@p3=9,@p4=10,@p5=11,@p6=12,@p7=16

Parece que desea or (Disjunction) en lugar de and (Conjunction). En este momento, usted está en busca de EstateFeatures objetos tales que cada objeto tiene varias Ids diferentes, lo que no parece ser lo que quiera.

var or = new Disjunction();
foreach(var id in idCollection)
    or.Add(Expression.Eq("MyFeatureValue.Id", id);

var query = DetachedCriteria.For<Estate>();
query
    .CreateCriteria("EstateFeatures")
    .Add(and);
var estates = query.GetExecutableCriteria(session).List<Estate>();

También intentado esto, pero el resultado es el mismo:

DetachedCriteria features = DetachedCriteria.For<FeatureValue>();
features.SetProjection(Projections.Property("Id"));
features.Add(Property.ForName("Id").EqProperty("value.Id"));

var and = new Conjunction();

foreach (var l in FeatureIdCollection)
    and.Add(Expression.Eq("Id", l));

features.Add(and);

query.CreateCriteria("EstateFeatures")
     .CreateCriteria("MyFeatureValue","value")
     .Add(Subqueries.Exists(features));
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top