Можете ли вы создать ограничение для отдельных критериев для примитивной коллекции?

Я хотел бы знать, есть ли способ создать ограничение для примитивной коллекции модели в NHibernate.3.3.3?

Вот подробности:

class Parent { 
    IEnumerable<string> ChildNames { get; set; }

}

Мне нужно искать так:

private DetachedCriteria BuildQuery() {
    var inNames = { "Bob", "Sam", "Dan" };
    var query = DetachedCriteria.For<Parent>("parent");
    query.Add(Restrictions.In("ChildNames", inNames));
    return query;
}

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

Если я смогу это сделать, а я полностью провалюсь, я тоже воспользуюсь этой помощью!


person bighead.dev    schedule 18.10.2013    source источник
comment
Отметьте [this] [1], используя ваше ограничение in clause. [1]: stackoverflow.com/questions/1209373/   -  person Najera    schedule 19.10.2013


Ответы (2)


В этом сценарии мы можем использовать Projection (что-то менее типобезопасное, затем сопоставленное свойство, но более гибкое).

Ожидаем такого отображения:

<bag name="ChildNames" inverse="false" lazy="true" table="[dbo].[ChildNames]" 
    cascade="all"
    batch-size="25">
  <key column="ParentId" />
  <element type="System.String" column="ChildName" />
</bag>

Затем мы можем настроить метод запроса Build следующим образом:

protected virtual DetachedCriteria BuildQuery()
{
    var inNames = new [] { "Bob", "Sam", "Dan" };

    // parent query reference
    var query = DetachedCriteria.For<Parent>("parent");
    // reference to child query
    var child = query.CreateCriteria("ChildNames");

    // let's project the column name of the Element, e.g. 'Name'
    var columnNameProjection = Projections.SqlProjection(
        "ChildName as name", null, new IType[] { NHibernateUtil.String }
        );

    // in clause
    child.Add(Restrictions.In(
        columnNameProjection, inNames
        ));

    return query;
}

И вот что мы получим:

SELECT ...
 FROM Parent this_ 
  inner join [dbo].[ChildNames] childNames3_ 
    on this_.ParentId=childNames3_.ParentId 
 WHERE ChildName in (@p0, @p1, @p2)
 ...
 @p0=N'Bob',@p1=N'Sam',@p2=N'Dan'

Предупреждение:

Пока это работает ... ChildName используется без псевдонима. Это может быть довольно сложно выполнить ... поэтому будьте осторожны, если в этом сценарии есть больше столбцов с именем ChildName

person Radim Köhler    schedule 19.10.2013

В итоге я, как и многие, преобразовал коллекцию в строгий тип.

person bighead.dev    schedule 24.10.2013