1

我試圖總結一些重複的代碼擴展方法,清理了一點東西。LINQ表達式與LINQ到實體

我試圖避免被檢查,如果一個字符串(通常是一個控件的文本值)爲空/空,如果是,它使用比較模式包含在我的數據的字段。顯然這個字段並不是硬編碼到我的擴展中,對象類型也不是。我得到的LINQ to Objects完美的工作,但我得到了泛型運行時錯誤「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 2012-02-28 21:50:02

+0

儘管如此,在一百萬年內!作品魅力,不錯! – RichardW1001 2012-02-28 22:22:40