Я написал запрос:
from order in session.Query<ORM.Entities.Order>()
where order.Finishable()
select order);
где Finishable - это метод, содержащий некоторую бизнес-логику, которая возвращает bool.
Nhibernate возвращает исключение System.NotSupportedException: Boolean Finishable().
Логика в Finishable() немного сложнее. Поэтому мои вопросы:
Итак, какое лучшее решение?
Любая фактическая именованная функция, которую вы пишете, собирается компилироваться компилятором и, таким образом, эффективно не используется поставщиком запросов 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);
Expression
чтобы поставщик запросов поддерживал их, да. То, как конкретно вы будете создавать эти выражения, может сильно различаться, и особенности того, как вы должны это делать, будут зависеть от ситуации. Да, работать с выражениями сложнее, чем просто писать код на C #; это природа написания кода на C #, который может быть интерпретирован и переведен на совершенно отдельный язык запросов (в частности, один менее мощный, чем C #). Это просто будет иметь некоторую сложность.