Запрашиваете коллекцию с помощью Nhibernate Criteria Api? - PullRequest
4 голосов
/ 11 февраля 2009

У меня есть объект «Estate», и у этого объекта есть коллекция «EstateFeatures» (тип: EstateFeature), а у EstateFeature есть свойство «MyFeatureValue».

Примечание: это ограниченные свойства для вопроса. У всех сущностей есть Id и все необходимые и т. Д.

Поместье

IList<EstateFeature> EstateFeatures;

EstateFeature

FeatureValue MyFeatureValue;

FeatureValue

public virtual long Id;

Я пытаюсь получить объекты недвижимости с указанным 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>();

Ничего не возвращено из этого запроса, я делаю что-то не так?

Спасибо

Ответы [ 7 ]

8 голосов
/ 11 февраля 2009

Если я правильно понимаю, я думаю, что-то вроде этого может работать

CreateCriteria(typeof(Estate))
     .CreateAlias("EstateFeatures", "estatefeature")
     .Add(Restrictions.In("estatefeature.MyFeatureValue.Id", ids))
     .List<Estate>();
2 голосов
/ 11 февраля 2009

Вам нужно будет убедиться, что вы присоединяетесь к MyFeatureValue один раз для каждой функции, которую вы хотите иметь в своем Estate.

Одним из способов является вызов .CreateAlias ​​для каждой итерации, присвоение ему уникального псевдонима и добавление выражения «aliasX.Id»


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


}

На самом деле не помнит, как работает синтаксис, написал это из моей головы, не уверен, если вам нужно переопределить запрос либо:)

Тем не менее, я думаю, что это поможет вам начать.

РЕДАКТИРОВАТЬ: поскольку ошибка в Criteria API не позволяет связать коллекцию несколько раз с помощью CreateAlias ​​или CreateCriteria, вам необходимо прибегнуть к HQL.

http://derek -says.blogspot.com / 2008/06 / дублированных ассоциации путь-черепашки-in.html

(Hibernate также страдает от той же проблемы)


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

вам нужно будет динамически построить HQL, чтобы ваши псевдонимы стали уникальными (fv1, fv2, fvX ...)

2 голосов
/ 11 февраля 2009

Какой запрос сгенерировал для вас NHibernate? Вы можете проверить это с помощью свойства конфигурации show_sql.

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

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

Если вы хотите получить все состояния, которые содержат все указанные функции, я думаю, вам придется использовать дизъюнкцию, чтобы NHibernate извлекал все состояния, которые имеют хотя бы одну из этих функций. Затем в своем клиентском коде вам нужно будет проверить каждое имущество в своем «клиентском коде», чтобы в конечном итоге вы просто получили все состояния.
Я не знаю, есть ли эффективный способ позволить NHibernate справиться с этим ...

1 голос
/ 11 февраля 2009

Код выглядит так, как будто вы передаете список FeaturesValueIds и хотите получить список со всеми этими функциями. Если это так, я бы посмотрел на генерируемый SQL-запрос и запустил его для базы данных, чтобы выяснить, нужно ли вам что-либо возвращать.

В противном случае, если вы ищете Список, в котором есть какие-либо функции, которые вы передаете, вам следует использовать Разъединение, а не Соединение.

0 голосов
/ 11 февраля 2009

Похоже, вы хотите or (Disjunction) вместо and (Conjunction). Сейчас вы ищете EstateFeature s объектов, так что каждый объект имеет несколько различных Id s, что, кажется, не то, что вы хотите.

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>();
0 голосов
/ 11 февраля 2009

Я тоже пробовал это, но результат тот же:

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));
0 голосов
/ 11 февраля 2009
    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
...