1

Я пытаюсь обернуть некоторый повторяющийся код в методе расширения, чтобы немного почистить вещи.Linq выражения с Linq to Entities

Шаблон, который я пытаюсь избежать, проверяет, является ли строка (обычно текстовое значение элемента управления) пустой/пустой, и если она есть, сравнивая ее, используя Содержит в поле в моих данных. Очевидно, что поле не жестко закодировано в моем расширении, и не является типом объекта.

То, что у меня отлично работает в Linq для объектов, но я получаю общую ошибку времени выполнения «LINQ to Entities не распознает метод« System.String Invoke (GenericQueryHelper.Customer) »и этот метод не могут быть переведены в выражение хранилища ». при использовании модели структуры сущности.

Вот что у меня есть:

<System.Runtime.CompilerServices.Extension()> 
Public Function CompareAndFilter(Of T)(source As System.Linq.IQueryable(Of T), expressionField As System.Linq.Expressions.Expression(Of System.Func(Of T, String)), compareTo As String) 
    If String.IsNullOrEmpty(compareTo) Then 
     Return source 
    Else 
     Dim compiledField As System.Func(Of T, String) = expressionField.Compile() 
     Return source.Where(Function(x) compiledField.Invoke(x).Contains(compareTo)) 
    End If 
End Function 

И я также пытался:

<System.Runtime.CompilerServices.Extension()> 
Public Function CompareAndFilter(Of T)(source As System.Linq.IQueryable(Of T), expressionField As System.Func(Of T, String), compareTo As String) 
    If String.IsNullOrEmpty(compareTo) Then 
     Return source 
    Else 
     Return source.Where(Function(x) expressionField.Invoke(x).Contains(compareTo)) 
    End If 
End Function 

С одинаковым исходом ...

Во-первых, это возможно? Я хочу, чтобы мое использование выглядеть примерно так:

Dim results = repository.Customers.CompareAndFilter(Function(c) c.FirstName, searchText) 

мне нужно, чтобы получить это работает против базы данных SQL на самом деле, как это фильтрация результатов, поэтому я не хочу делать это в памяти. Любые мысли?

ответ

2

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

Следующая может быть в состоянии сделать то, что вы после:

<System.Runtime.CompilerServices.Extension()> 
Public Function CompareAndFilter(Of T)(source As System.Linq.IQueryable(Of T), expressionField As System.Linq.Expressions.Expression(Of System.Func(Of T, String)), compareTo As String) 
    If String.IsNullOrEmpty(compareTo) Then 
     Return source 
    Else 
     Return source.GroupBy(expressionField) 
      .Where(Function(g) g.Key.Contains(compareTo)) 
      .SelectMany(Function(g) g) 
    End If 
End Function 

GroupBy используется для выбора поля, указанного expressionField, то ключ проверяется, и элементы в каждой группе возвращаются.

+0

+1. Умная идея. – StriplingWarrior

+0

Никогда бы этого не произошло за миллион лет! Работает шарм, хороший! – RichardW1001

3

Да, это возможно, но оно включает в себя expression манипуляции. Вы можете либо parse the expression you're given and build the new criterion expression, либо иметь LINQKit выполнить обход дерева для вас.

+0

Некоторые хорошие материалы для чтения, спасибо! Возможно, вы просто ответили на целую кучу будущих вопросов! – RichardW1001

 Смежные вопросы

  • Нет связанных вопросов^_^