1

我试图在扩展方法中包装一些重复的代码,以清理一下。

我试图避免的模式是检查字符串(通常是控件的文本值)是否为空/空,如果是,则使用包含将其与我的数据中的字段进行比较。显然,该字段没有硬编码到我的扩展中,对象类型也没有。

我所拥有的在 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 数据库上运行它,因为它正在过滤结果,所以我不想在内存中这样做。有人有什么想法吗?

4

2 回答 2

3

是的,这是可能的,但它涉及表达式操作。您可以解析给定的表达式并自己构建新的标准表达式,或者让LINQKit为您执行树遍历。

于 2012-02-28T21:15:11.693 回答
2

Linq to entity 不了解如何调用委托,它需要一个表达式来计算要生成的 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,然后检查键,并返回每个组中的项目。

于 2012-02-28T21:18:40.353 回答