4

我有一个“Estate”实体,该实体有一个集合“EstateFeatures”(类型:EstateFeature),EstateFeature 有一个属性“MyFeatureValue”。

注意:这些是问题的有限属性。所有实体都有一个 ID 和所有必需的等

财产

IList<EstateFeature> EstateFeatures;

房地产特征

FeatureValue MyFeatureValue;

特征值

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>();

此查询没有返回任何内容,我做错了什么吗?

谢谢

4

7 回答 7

8

如果我理解正确,我认为这样的事情可能会奏效

CreateCriteria(typeof(Estate))
     .CreateAlias("EstateFeatures", "estatefeature")
     .Add(Restrictions.In("estatefeature.MyFeatureValue.Id", ids))
     .List<Estate>();
于 2009-02-11T20:30:35.160 回答
2

NHibernate 为您生成了什么查询?您可以使用 show_sql 配置属性进行检查。

当我看到您的查询时,您正在尝试获取具有给定功能集的所有庄园。我认为,这将生成一个看起来像的查询

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

如果你想检索包含所有指定特征的所有庄园,我认为你必须使用析取,以便 NHibernate 检索至少具有这些特征之一的所有庄园。然后,在您的客户代码中,您将检查您的“客户代码”中的每个庄园,以便最终得到具有所有功能的庄园。
我不知道是否有一种有效的方法让 NHibernate 处理这个......

于 2009-02-10T23:02:30.360 回答
2

您需要确保为您希望您的遗产拥有的每项功能加入一次 MyFeatureValue。

一种方法是为每次迭代调用 .CreateAlias,给它一个唯一的别名,然后添加表达式“aliasX.Id”

foreach(idCollection 中的变量 id)
{
   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/duplicate-association-path-bug-in.html

(Hibernate 也有同样的问题)

选择 e   
来自房地产公司
INNER JOIN e.MyFeatureValue AS fv1
INNER JOIN e.MyFeatureValue AS fv2
其中 fv1.Id = 3
   和 fv2.Id = 13

您将需要动态构建 HQL,以便您的别名变得独一无二(fv1、fv2、fvX ...)

于 2009-02-10T23:30:55.033 回答
1

该代码看起来像您正在传递一个 FeaturesValueIds 列表,并且想要一个具有所有这些功能的列表。如果是这种情况,我会查看正在生成的 SQL,并针对数据库运行它,看看是否应该取回任何东西。

否则,如果您正在寻找包含您要传入的任何特征的列表,您应该使用析取而不是合取。

于 2009-02-10T22:57:06.067 回答
0
    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
于 2009-02-10T23:22:25.147 回答
0

看起来您想要or( Disjunction) 而不是and( Conjunction)。现在,您正在搜索EstateFeatures 对象,使得每个对象都有多个不同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>();
于 2009-02-11T14:02:34.143 回答
-1

我也试过这个,但结果是一样的:

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));
于 2009-02-11T00:44:38.447 回答