到目前为止,我们有一个搜索tenantName列的方法(OnSearchButtonClick):
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”的组中查找一个tennant,我们希望在searchValue参数中传递“Runners”并在new参数中分组,然后执行查看group列的查询。 (如果第二个参数是TenantName,我们应该查看TenantName列)
有没有人知道我们如何才能做到这一点?非常感谢所有帮助。
答案 0 :(得分: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。然后我们得到相应的值,然后我们发回这个值。
答案 1 :(得分: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());
}
这种方法过于复杂,无法满足本案例的需要。但是,当条件比将变量属性与常量字符串进行比较时更复杂,它可能会派上用场。
答案 2 :(得分: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