Ковариант QueryOver коллекция в NHibernate - PullRequest
0 голосов
/ 28 мая 2018

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

public IqueryOver<T, T> Join(QueryOver<T, T> main, params QueryOver[] others)
{
    var result = main.GetExecutableQueryOver(Session);

    foreach(var subQuery in others)
         result = result.WithSubQuery.WhereProperty(IdPicker).In(subQuery);

    return result;
}

, где IdPicker - это лямбда, которая выбирает соответствующее свойство в зависимости от хранилища.

Теперь все это работает хорошо и генерирует SQL следующим образом:

SELECT ...
FROM <TABLE> this_
WHERE ...
AND this_.ID in (<subquery>)

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

params QueryOver<IAnimal, IAnimal>[] others

Но это все еще не решает проблему, так как я получаю ошибку cannot convert from QueryOver< Dog, Dog> to QueryOver< IAnimal, IAnimal>,Конечно, Dog реализует IAnimal, но есть проблема ковариации.

Поскольку Medo42 предлагает , если бы у меня был доступ к иерархии классов QueryOver, я мог бы сделать ее производной от другого класса,но я не знаю.

Я знаю, что мог бы заставить метод принимать только один параметр за раз, а затем вызывать его для каждого подзапроса, но я хотел бы избежать этого и сделать его более общим.Другое решение, которое я рассмотрел, - создание расширения для объекта QueryOver <,> и создание цепочки соединения, но для этого требуется статический метод, что означает, что я не могу использовать объект IdPicker или Session.

Iв итоге тем временем использовалось ключевое слово dynamic для решения (dynamic[] others), но, как я понимаю, его следует использовать только в качестве крайней меры.

Итак, вопрос в том, есть ли другой способрешить это?

...