2

ラムダ式の扱いに問題があります。私はEFの下でMVCを使用しており、すべてのモデルが継承する「メタモデル」を作成し、それを使用してLinqで要素をリストする方法を作成しようとしています。

これは「メタモデル」なので、クラスの定義がわかりません。

私はこれをやろうとしています.Modelクラス「Customer」があると仮定します

    Public Function List(searchText As String) As List(Of Customer)
        With EFContext
            Return .Customers.AsQueryable().Where((Function(Customer) Customer.Name.Contains(searchText)).ToList()
       End With
   End Function

しかし、私はそれを汎用にしたいので、継承クラスのプロパティ名を渡し、このプロパティで検索 (および並べ替え) できるようにしたいと考えています。

これが私の最善のアプローチです:

    Public MustInherit Class BaseBL

    Public Function AutoList(Of T)(conf As ConfigurationBL) As List(Of T)
        Dim items As List(Of T)
        Dim sortParam = Expression.Parameter(GetType(T), "param")
        Dim sortFunc = Expression.Convert(Expression.Property(sortParam, conf.SortField), GetType(Object))
        Dim sortExpr = Expression.Lambda(Of Func(Of T, Object))(sortFunc, sortParam).Compile()

        Dim searchFunc As Func(Of T, Boolean) = Function(param)
                                                    Dim prInfo As PropertyInfo = param.GetType.GetProperty(conf.SearchField)
                                                    Dim str As String = prInfo.GetValue(param, Nothing)
                                                    Return str.Contains(conf.SearchText)
                                                End Function

        Dim searchExpr As Expression(Of Func(Of T, Boolean)) = Function(param) searchFunc(param)

        Dim query As IQueryable(Of T) = GetQueryable(Of T)()

        items = query.Where(searchExpr).OrderBy(sortExpr).ToList() '.Skip(conf.PageSize * (conf.PageNumber - 1)).Take(conf.PageSize).ToList()

        Return items
    End Function

    Public MustOverride Function GetQueryable(Of T)() As IQueryable(Of T)
End Class

このクラスはジェネリック クラス T の親であるため、GetQueriable(Of T) メソッドは子クラスに実装されます。

ConfigurationBL クラスには、適切な構成を提供する sortField、searchField、および searchText が含まれています。

これはほとんど機能します。sortExpr で orderBy を実行します。searchExpr で where を実行すると、それも機能します。

一緒にやろうとすると問題が発生します。例外が発生します。

「式 LINQ 'Invoke' ノードは LINQ to Entities ではサポートされていません」

これは私が使用しているためだと確信しています

Dim searchExpr As Expression(Of Func(Of T, Boolean)) = Function(param) searchFunc(param)

適切な式ツリーの代わりに、searchFunc を式ツリーに変換する方法がわかりません。

私は本当にこれに固執しました、私は本当に助けとアイデアをいただければ幸いです、ありがとう:)

4

1 に答える 1

1

最後に、自分で修正することができました.searchExprをこれに置き換えました

Dim searchExpr = getSearchExpression(Of T)(conf.SearchField, conf.SearchText).Compile()

どこ...

Private Function getSearchExpression(Of T)(propName As String, search As String) As Expression(Of Func(Of T, Boolean))
        Dim element As ParameterExpression = Expression.Parameter(GetType(T), "element")
        Dim propertyValue As ParameterExpression = Expression.Variable(GetType(String), "propertyValue")
        Dim searchText As ParameterExpression = Expression.Variable(GetType(String), "searchText")

        Dim asgPropertyValue As Expression = Expression.Assign(propertyValue,
            Expression.Convert(Expression.Property(element, propName), GetType(String))
        )

        Dim asgSearchText As Expression = Expression.Assign(searchText,
           Expression.Constant(search)
           )

        Dim callContains As Expression = Expression.Call(propertyValue, GetType(String).GetMethod("Contains"), searchText)


        Dim block As Expression = Expression.Block(GetType(Boolean),
                                   New List(Of ParameterExpression)({propertyValue, searchText}),
                                   asgPropertyValue,
                                   asgSearchText,
                                   callContains
                               )      

        Return Expression.Lambda(Of Func(Of T, Boolean))(block, element)
    End Function

これが誰かの助けになることを願っています、こんにちは:)

于 2012-07-19T11:40:05.773 に答える