Nhibernate использовать функции расширения в Query

1

Я написал запрос:

from order in session.Query<ORM.Entities.Order>()
                                  where order.Finishable()
                                  select order);

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

Nhibernate возвращает исключение System.NotSupportedException: Boolean Finishable().

Логика в Finishable() немного сложнее. Поэтому мои вопросы:

  1. Что я могу сделать, чтобы разрешить использование пользовательских функций в запросах? Нужно ли мне менять подпись метода?
  2. Это даже хорошая идея сделать это таким образом? Я мог бы также попытаться переписать логику для работы с nhibernate. Это приведет к дублированию логики как-то. Неужели это неизбежно в этом случае?
  3. Я мог бы также попытаться извлечь все данные, необходимые для вычисления Finishable() после этого, поэтому сначала получите все Orders и заполните их данными, а после этого я могу использовать свою функцию как есть.

Итак, какое лучшее решение?

Теги:
nhibernate

1 ответ

1
Лучший ответ

Любая фактическая именованная функция, которую вы пишете, собирается компилироваться компилятором и, таким образом, эффективно не используется поставщиком запросов LINQ.

Вам нужно создать Expression которое представляет операцию, которая у вас есть.

Вы почти наверняка хотите использовать лямбду для создания этого выражения, но вам необязательно всегда встраивать эти лямбды, как это обычно бывает. Вы можете создать поле method/property/, в котором хранится выражение, которое вы хотите открыть, в большую область:

public class Order
{
    //consider renaming as appropriate
    public static Expression<Func<Order, bool>> Finishable
    {
        get
        {
            //TODO change logic in lambda as needed
            return order => order.Status == "Finished";
        }
    }
}

Затем вы можете написать:

var query = session.Query<ORM.Entities.Order>()
    .Where(ORM.Entities.Order.Finishable);
  • 0
    Спасибо за ваш быстрый ответ. Чтобы реализовать этот подход, я должен рекурсивно изменить каждую функцию и преобразовать их в выражения. В более общем случае, это всегда лучший подход? Есть ли случаи, когда это было бы невозможно? Мне кажется, что это приведет к более сложной модели, в которой реализация будет управляться конкретной используемой платформой.
  • 0
    @Kalkas Вам понадобится логика в объектах Expression чтобы поставщик запросов поддерживал их, да. То, как конкретно вы будете создавать эти выражения, может сильно различаться, и особенности того, как вы должны это делать, будут зависеть от ситуации. Да, работать с выражениями сложнее, чем просто писать код на C #; это природа написания кода на C #, который может быть интерпретирован и переведен на совершенно отдельный язык запросов (в частности, один менее мощный, чем C #). Это просто будет иметь некоторую сложность.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню