我正在尝试在扩展方法中包含一些重复的代码,以便稍微清理一下。
我试图避免的模式是检查字符串(通常是控件的文本值)是否为空/空,如果是,则使用Contains将其与我的数据中的字段进行比较。显然,该字段没有硬编码到我的扩展中,对象类型也没有。
我在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数据库运行,因为它是过滤结果,所以我不想在内存中这样做。有人有什么想法吗?
答案 0 :(得分:3)
是的,这是可能的,但它涉及expression操纵。您可以自己parse the expression you're given and build the new criterion expression,也可以让LINQKit为您执行树遍历。
答案 1 :(得分:2)
Linq to entities不了解如何调用委托,它需要一个表达式来计算出要生成的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
指定的字段,然后检查密钥,并返回每个组中的项目。