2

So far we have a method (OnSearchButtonClick) which searches on the tenantName column:

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

In this method we want to pass another string as a parameter with the name of a certain column of TenantOverviewDto. For example if we want to look for a tennant in a group called "Runners" we want to pass "Runners" in the searchValue parameter and group in the new parameter and then execute a query which looks in the group column. (If the second parameter is TenantName we should look in the TenantName column)

Does anyone have an idea of how we can accomplish this? All help is very much appreciated.

Gert Hermans
  • 769
  • 1
  • 9
  • 30
  • 2
    I don't have to much knowledge about lambda, but would this be useful in any way? http://stackoverflow.com/questions/1196991/get-property-value-from-string-using-reflection-in-c-sharp – WozzeC Nov 05 '12 at 15:04
  • It would be useful if in the gui there is a search section with a textbox to enter the value and a combobox where you can select the column on which you want to search. We've found a solution : I'll post it soon. – Gert Hermans Nov 05 '12 at 15:07
  • Super, I found this question intresting since I am a big fan of Generic/Reusable code :) Looking forward to the solution. – WozzeC Nov 05 '12 at 15:10
  • Even though at first it seems cool to have something like that, you are potentially looking to also have lots of potential maintenance nightmare later. So be prepared. Unless, of course, you passing the project to someone else. :) I would suggest looking into the manual wiring, but optimize that as much as possible. With more detail from you, I could elaborate on what I mean by that. – Victor Zakharov Dec 16 '13 at 22:07

3 Answers3

1

My collegue has found a solution with reflection. the method looks like this:

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

In the GetPropertyValue method we'll use reflection:

 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

First we get the type of object we passed (in this case TenantOverviewDto). Second we get the propertyInfo of the columnName we've passed. Then we get the corresponding value and we send this one back.

Gert Hermans
  • 769
  • 1
  • 9
  • 30
  • I don't know why you say this solution is about generics/lambda. It uses reflection, just like WozzeC proposed in his comment. – Cristian Lupascu Nov 05 '12 at 15:21
  • My mistake, It uses reflection i'll change that – Gert Hermans Nov 05 '12 at 15:24
  • Looked at the link of WozzeC too late. This is what we needed indeed. Thanx – Gert Hermans Nov 05 '12 at 15:26
  • What I want to know now is if it is possible to use getProperty in lambda. Thus not adding a separate function to achieve the goal. – WozzeC Nov 05 '12 at 15:27
  • We can put it all in the lambda expression, but it still uses reflection.This works: .Where(Function(p) p.GetType().GetProperty(columnName).GetValue(p, Nothing).ToUpper().StartsWith(searchValue.ToUpper())).ToList()) – Gert Hermans Nov 05 '12 at 15:36
0

In this case, the reflection solution is simpler and more concise, therefore I'd prefer to use it.

However, I thought it was interesting to post a C# solution using dynamic expressions:

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());
}

This approach is much too complex for what's needed in this case. However, it could come in handy when the condition more complex than just comparing a variable property to a constant string.

Cristian Lupascu
  • 39,078
  • 16
  • 100
  • 137
0

try This solution :

Private Sub OnSearchButtonClick(ByVal searchValue As String, ByVal columnName As String)
    _filteredTenants = _filteredTenants.findAll(f=>f[columnName].toString().StartsWith(searchValue.ToUpper())).toList()
End Sub
Mark Parnell
  • 9,175
  • 9
  • 31
  • 36