2

到目前为止,我们有一个方法 (OnSearchButtonClick) 可以在tenantName 列上进行搜索:

Private Sub OnSearchButtonClick(ByVal searchValue As String)
            _filteredTenants = New ListCollectionView(_allTenants.Cast(Of TenantOverviewDto).Where(Function(p) p.TenantName.ToUpper().StartsWith(searchValue.ToUpper())).ToList())
 End Sub

在这个方法中,我们要传递另一个字符串作为参数,其中包含 TenantOverviewDto 的某个列的名称。例如,如果我们想在名为“Runners”的组中查找租户,我们希望在 searchValue 参数中传递“Runners”,并在新参数中传递 group,然后执行在 group 列中查找的查询。(如果第二个参数是 TenantName,我们应该查看 TenantName 列)

有谁知道我们如何做到这一点?非常感谢所有帮助。

4

3 回答 3

1

我的同事通过反思找到了解决方案。该方法如下所示:

Private Sub OnSearchButtonClick(ByVal searchValue As String, ByVal columnName As String)

            _filteredTenants = New ListCollectionView(_allTenants.Cast(Of TenantOverviewDto).Where(Function(p) GetPropertyValue(p, columnName).ToUpper().StartsWith(searchValue.ToUpper())).ToList())
End Sub

在 GetPropertyValue 方法中,我们将使用反射:

 Private Function GetPropertyValue(ByVal o As Object, ByVal propertyName As String) As Object

            Dim type As Type = o.GetType()
            Dim info As PropertyInfo = type.GetProperty(propertyName)
            Dim value As Object = info.GetValue(o, Nothing)
            Return value

        End Function

首先,我们获取我们传递的对象类型(在本例中为 TenantOverviewDto)。其次,我们得到我们传递的 columnName 的 propertyInfo。然后我们得到相应的值并将这个值发回。

于 2012-11-05T15:14:35.393 回答
0

在这种情况下,反射解决方案更简单,更简洁,因此我更喜欢使用它。

但是,我认为使用动态表达式发布 C# 解决方案很有趣:

private void OnSearchButtonClick(string propertyName, string searchValue)
{
    var parameter = Expression.Parameter(typeof(TenantOverviewDto), "p");

    var toUpperMethodInfo = typeof(string).GetMethods()
        .Single(m => m.Name == "ToUpper" && !m.GetParameters().Any());

    var startsWithMethodInfo = typeof(string).GetMethods()
        .Single(m => m.Name == "StartsWith" && m.GetParameters().Count() == 1);

    var expression =
        Expression.Call(
            Expression.Call(
                Expression.Property(parameter, propertyName), 
                toUpperMethodInfo),
            startsWithMethodInfo,
            Expression.Constant(searchValue.ToUpper())
        );

    var compiledCondition = Expression.Lambda<Func<TenantOverviewDto, bool>>
        (expression, parameter).Compile();

    _filteredTenants = new ListCollectionView(
        _allTenants.Cast<TenantOverviewDto>().Where(compiledCondition).ToList());
}

这种方法对于这种情况下需要的东西来说太复杂了。但是,当条件比仅将变量属性与常量字符串进行比较更复杂时,它可能会派上用场。

于 2012-11-05T15:32:20.287 回答
0

试试这个解决方案:

Private Sub OnSearchButtonClick(ByVal searchValue As String, ByVal columnName As String)
    _filteredTenants = _filteredTenants.findAll(f=>f[columnName].toString().StartsWith(searchValue.ToUpper())).toList()
End Sub
于 2013-12-16T21:25:10.600 回答