Итак, вот ситуация: предположим, у меня есть структура класса, используемая для представления гибкого поиска:
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
s я не могу использовать стратегию select
(приведет к выбору N + 1).
Однако выборка с использованием JoinQueryOver
или 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();