所以情况是这样的:假设我有一个用于表示灵活搜索的类结构:
public class SearchDefinition
{
public virtual string Name {get; set;}
public virtual IEnumerable<SearchTerm> Terms {get; set;}
}
public abstract class SearchTerm
{
public virtual Operator Op {get; set; } //i.e 'In', 'Not in', 'Contains' etc..
public abstract IEnumerable<object> CompareValues {get; } //the values against which the search is performed. for example- 'in (2,6,4)', 'contains ('foo', 'blah')'.
}
现在,由于搜索词可以引用不同的字段,因此每种类型的词都有自己的类:
public class NameSearchTerm : SearchTerm
{
public virtual IEnumberable<string> ConcreteValues {get; set;}
public override IEnumberable<object> CompareValues
{
get
{
return ConcreteValues.Cast<object>();
}
}
}
等等,具有不同类型的集合。
术语使用每个层次结构表进行映射,除了ConcreteValues
集合,映射到不同的表(字符串值的表,int 值的表等)。
我的问题是 - 我如何有效地检索列表SearchDefinition
是?为收集SearchTerm
我不能使用select
策略(将导致选择 N+1)。
但是,使用获取JoinQueryOver
or JoinAlias
,在发送正确的查询时,不会填充集合:
var definitions = session.QueryOver<SearchDefinition>()
.Where(/*condition*/)
.JoinAlias(d=> d.Terms, () => termsAlias)
.List(); //sends a correct, joined query which fetches also the terms from the terms table
Assert.IsTrue(NHibernateUtil.IsInitialized(definitions[0].Terms)); //THIS FAILS!
关于如何做到这一点有什么建议吗?
我在这里添加流畅的映射 -
里面的术语集合SearchDefinition
班级:
mapping.HasMany(x => x.Terms)
//.Not.LazyLoad()
.Fetch.Subselect()
.Cascade.AllDeleteOrphan()
.Cache.ReadWrite();
具体值集合内IntSearchTerm
班级(所有学期班级均类似):
mapping.HasMany<int>(t=> t.ConcreteValues).Table("TermsIntValues").Element("IntValue")
//.Not.LazyLoad()
.Fetch.Subselect()
.Cascade.AllDeleteOrphan();