1

Although very similar to another question. Other question

I am wondering how to do that and support dot notation with nested objects. My current extension to IQueryable looks like this.

public static IQueryable<T> WherePropStringContains<T>(this IQueryable<T> query, string propertyName, string contains)
    {
        var parameter = Expression.Parameter(typeof(T), "x");
        var propertyExpression = Expression.Property(parameter, propertyName);
        var method = typeof(string).GetMethod("Contains", new[] { typeof(string) });
        var someValue = Expression.Constant(contains, typeof(string));
        var containsExpression = Expression.Call(propertyExpression, method, someValue);
        var lmd = Expression.Lambda<Func<T, bool>>(containsExpression, parameter);

        return query.Where(lmd);
    }

I would like for the property name to support something like "User.Name.First" which if i wasn't using string and generic might look like query.where(x => x.User.Name.First.Contains(contains)

Thanks

Community
  • 1
  • 1
matthewdaniel
  • 1,842
  • 4
  • 21
  • 35

1 Answers1

0

Does this look similar to what you're looking for?

public static class Extensions {
    public static IQueryable<T> WherePropStringContains<T>(this IQueryable<T> queryable, String name, String value) {
        IEnumerable<String> propertyNames = name.Split('.');

        return queryable.Where(x => ObjectChainHasProperties(x, propertyNames, value));
    }

    private static bool ObjectChainHasProperties(Object obj, IEnumerable<String> propertyNames, String value) {
        IEnumerator<String> enumerator = propertyNames.GetEnumerator();

        while (obj != null && enumerator.MoveNext()) {
            obj = obj.GetType().GetProperties()
                .Where(p => p.Name == enumerator.Current)
                .FirstOrDefault()?
                .GetValue(obj);
        }

        return (obj as String) == value;
    }
}
Eduard Malakhov
  • 1,095
  • 4
  • 13
  • 25