Пишу Extension для IQueryablelist (EntityFramework)
IQueryablelist= db.Users;//Users table
//Поиск символа "a" в полях которые передаю, это FirstName or LastName
list.ApplyFilterPatern("a", x => x.FirstName, x => x.LastName,...);
//результат работы аналогичен коду
list.Where(x => x.FirstName.ToLower().Contains("a") || x.LastName.ToLower().Contains("a"))
Вот что получилось написать
https://dotnetfiddle.net/zrGPfb
Дальше я запутался с lambda и generics
public class User
{
public string FirstName
{
get;
set;
}
public string LastName
{
get;
set;
}
public string MiddleName
{
get;
set;
}
}
public class Program
{
public static void Main()
{
List<User> users = new List<User>();
users.Add(new User { FirstName = "a", LastName = "b" } );
users.Add(new User { FirstName = "b", LastName = "a" } );
users.Add(new User { FirstName = "b", LastName = "b" } );
IQueryable<User> l = users.AsQueryable<User>();
var r = ApplyFilterPatern(l, "a", x => x.FirstName, x => x.LastName);
}
public static IQueryable<T> ApplyFilterPatern<T>(IQueryable<T> source, string searchString, params Expression<Func<T, object>>[] properties)
{
Expression result = null;
foreach (var item in properties)
{
var lambda = item as LambdaExpression;
MemberExpression memberExpression;
if (lambda.Body is UnaryExpression)
{
var unaryExpression = (UnaryExpression)lambda.Body;
memberExpression = (MemberExpression)unaryExpression.Operand;
}
else
{
memberExpression = (MemberExpression)lambda.Body;
}
var expr = Expression.Call(memberExpression, "ToLower", null, null);
expr = Expression.Call(expr, typeof (string).GetMethod("Contains", new[] { typeof (string)}), Expression.Constant(searchString));
if (result == null)
result = expr;
else
result = Expression.Or(result, expr);
}
var parameter = Expression.Parameter(typeof (T), "x");
var r = Expression.Lambda<Func<T, bool>>(result, parameter);
Type predType = typeof (Func<, >).MakeGenericType(typeof (T), typeof (bool));
Type predType2 = typeof (Expression<>).MakeGenericType(predType);
MethodInfo mWhere = typeof (Queryable).GetMethods().Single(
method => method.Name == "Where"
&& method.IsGenericMethodDefinition
&& method.GetGenericArguments().Length == 1
&& method.GetParameters().Length == 2
&& method.GetParameters()[1].ParameterType.GetGenericArguments().Length == 1
&& method.GetParameters()[1].ParameterType.GetGenericArguments()[0].GetGenericArguments().Length == 2);
mWhere = mWhere.MakeGenericMethod(predType2);
mWhere.Invoke(null, new object[] { source, r } );
return source;
}
}
Run-time exception (line 82): Object of type 'System.Linq.EnumerableQuery`1[ASE.User]' cannot be converted to type 'System.Linq.IQueryable`1[System.Linq.Expressions.Expression`1[System.Func`2[ASE.User,System.Boolean]]]'.
Смелости хватает только под ником писать?