Как я могу использовать выражения внутри операторов LINQ? - PullRequest
19 голосов
/ 12 июня 2009

Мне нравится повторно использовать выражения по СУХИМЫМ причинам, но как мне повторно использовать выражения в операторе LINQ?

, например

У меня есть

public static class MyExpressions {
    public static Expression<Func<Product,bool>> IsAGoodProduct() {
        return (p) => p.Quality>3;
    }
}

И хотел бы использовать это в операторах LINQ, поэтому

  var goodProds = from p in dataContext.Products
                  where ????? // how do I use IsAGoodProduct here?
                  select p;

Конечно, я мог бы использовать функцию IQueryableExtension.Where, но это сделало бы объединения и другие функции намного более утомительными для более сложных запросов.

Возможно ли это или это ограничение LINQ?

Ответы [ 4 ]

22 голосов
/ 12 июня 2009

Если вы переходите с синтаксического сахара LINQ, это возможно:

var goodProds = dataContext.Products.Where(MyExpressions.IsAGoodProduct());

Без этого невозможно.

Ничто не мешает вам смешать два стиля для создания одного запроса.

Пример:

  var goodProds = from p in dataContext.Products
                                       .Where(MyExpressions.IsAGoodProduct())
                  group p by p.Category into g 
                  select new {Category = g.Key, ProductCount = g.Group.Count()};
4 голосов
/ 17 января 2015

У меня была та же проблема, и я хотел сохранить возможность использовать методы расширения в синтаксисе запроса (как с обычными поддерживаемыми функциями ...). Решением может быть эта библиотека (спойлер: я автор).

Вы просто реализуете метод повторного использования дважды, один раз для общего использования и один раз для запросов.

public static class MyFunctions {
    [InjectLambda]
    public static bool IsAGoodProduct(Product product) {
        return product.Quality>3;
    }
    public static Expression<Func<Product,bool>> IsAGoodProduct() {
        return (p) => p.Quality>3;
    }
}

Фактический запрос может выглядеть как ожидаемый.

var goodProds = from p in dataContext.Products.ToInjectable()
                where p.IsAGoodProduct()
                select p;

Вызов ToInjectable создает облегченный прокси, который заменяет вызов метода IsAGoodProduct (если помечен соответствующим образом) на желаемое лямбда-выражение. Таким образом, вы можете использовать методы расширения везде, где внутри запроса работают параметризованные методы.

3 голосов
/ 14 июня 2012

У нас была такая же проблема. Он не поддерживается "из коробки" и является серьезной проблемой для LOB-приложений. В итоге я написал статью проекта кода о повторном использовании выражений LINQ, включая очень маленькую утилиту LinqExpressionPrjection, которая позволяет повторное использование в проекциях (в том числе в анонимных типах).

Найти статью здесь .

Вы можете получить сборку для повторного использования проекции в виде пакета nuget , а источник включен в CodePlex .

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

1 голос
/ 24 августа 2009

Кстати, я натолкнулся на эту полезную статью , в которой объясняется, как вы можете создавать динамические запросы LINQ, которые ссылаются на функции, упакованные в выражения, используя пользовательский метод расширения ToExpandable (). Предоставленное решение можно использовать в различных частях запроса LINQ, сохраняя при этом использование синтаксиса понимания вместо использования лямбда-синтаксиса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...