我们有一个通用的数据库架构:
对象< - AttributeValue - >属性
我们可以说我们谈论房屋。房子可以有很多很多属性(门形,屋顶颜色等)。混凝土房屋的属性数量尚不清楚。
使用直接映射到对象:
现在简单的按预期工作:
ICriteria criteria = this.Repository.CreateCriteria(typeof(House))
IList<House> searchResult = this.Repository.GetList<House>();
返回具有属性值集合(带有属性对象)的House。
我们需要找到特定的房子(有大窗户和玻璃门)并获得所有属性。
选择我想象的语句(不介意表现)并不神奇:
SELECT
this_.*,
att_val_fetch.*,
att_fetch.*
FROM House this_
INNER JOIN attribute_value att_val_fetch ON this_.versionedobjectid = att_val_fetch.versionedobjectid
INNER JOIN attribute att_fetch ON att_val_fetch.attributeid = att_fetch.attributeid
-- only for filter, no need to fetch
INNER JOIN attribute_value att_val_1 ON this_.versionedobjectid = att_val_1.versionedobjectid
INNER JOIN attribute att_1 ON att_val_1.attributeid = att_1.attributeid
INNER JOIN attribute_value att_val_2 ON this_.versionedobjectid = att_val_2.versionedobjectid
INNER JOIN attribute att_2 ON att_val_2.attributeid = att_2.attributeid
WHERE((att_1.attributename = 'window' AND att_val_1.valuestring IN('big'))
and (att_2.attributename = 'door' AND att_val_2.valuestring IN('glass')));
如何使用NHibernate(或Hibernate)完成此操作?很想在代码中看到没有直接SQL语句的解决方案,但实际上任何解决方案都是受欢迎的。
答案 0 :(得分:1)
也许你需要一个HQL查询示例(QBE)。
答案 1 :(得分:0)
假设这个简单的定义
class House
{
public int Id{get;set;}
.
.
.
public IList<AttributeValue> AttributeValues {get;set;}
}
class AttributeName
{
public int Id{get;set;}
.
.
.
public string Name{get;set;}
}
class AttributeValue
{
public int Id{get;set;}
.
.
.
public House House {get;set;}
public AttributeName Attribute{get;set;}
public string Value {get;set;}
}
和适当的相应映射,这个标准应该完成工作
ICriteria criteria = this.Repository.CreateCriteria(typeof(House))
criteria.CreateAlias("AttributeValues", "av");
criteria.SetFetchMode("av", FetchMode.Select);
criteria.Add(Expression.Eq("av.Attribute.Name", "door") && Expression.Eq("av.Value", "glass"));
criteria.Add(Expression.Eq("av.Attribute.Name", "window") && Expression.Eq("av.Value", "big"));
IList<House> houses = criteria.List<House>();
如果使用别名集合是正确的,或者需要完整的属性名称,其中我现在不记得现在设置获取模式
criteria.SetFetchMode("AttributeValues", FetchMode.Select);