我在处理 lambda 表达式时遇到了麻烦。我正在EF下使用MVC,我试图创建一个“MetaModel”,每个模型都将继承它,并用它创建一个使用Linq列出元素的方法。
因为这是一个“元模型”,所以我不知道类的定义。
我正在尝试这样做,假设我们有一个模型类“客户”
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 的 Parent,因此 GetQueriable(Of T) 方法将在子类上实现。
ConfigurationBL 类包含将提供正确配置的 sortField、searchField 和 searchText。
这几乎可以工作。我用 sortExpr 执行 orderBy 它可以工作,如果我用 searchExpr 执行 where 它也可以工作。
当我试图一起做所有事情时,问题就来了。它引发了一个异常:
“LINQ to Entities 不支持表达式 LINQ 'Invoke' 节点”
我很确定这是因为我使用
Dim searchExpr As Expression(Of Func(Of T, Boolean)) = Function(param) searchFunc(param)
而不是正确的表达式树,但我不知道如何将 searchFunc 转换为表达式树。
我真的坚持这一点,我非常感谢任何帮助和想法,谢谢:)