Encontré una solución que funciona dentro del framework .Net. Aquí un método que aún está en curso, pero funciona, y funciona para LINQ a Entidades:
public PagedViewModel<T> Filter<TValue>(Expression<Func<T, TValue>> predicate, FilterType filterType = FilterType.Equals) {
var name = (predicate.Body as MemberExpression ?? ((UnaryExpression)predicate.Body).Operand as MemberExpression).Member.Name;
var value = Expression.Constant(ParamsData[name].To<TValue>(), typeof (T).GetProperty(name).PropertyType);
// If nothing has been set for filter, skip and don't filter data.
ViewData[name] = m_QueryInternal.Distinct(predicate.Compile()).ToSelectList(name, name, ParamsData[name]);
if (string.IsNullOrWhiteSpace(ParamsData[name]))
return this;
var nameExpression = Expression.Parameter(typeof(T), name);
var propertyExpression = Expression.Property(nameExpression, typeof(T).GetProperty(name));
// Create expression body based on type of filter
Expression expression;
MethodInfo method;
switch(filterType) {
case FilterType.Like:
method = typeof(string).GetMethod("Contains", new[] { typeof(string) });
expression = Expression.Call(propertyExpression, method, value);
break;
case FilterType.EndsWith:
case FilterType.StartsWith:
method = typeof(string).GetMethod(filterType.ToString(), new[] { typeof(string) });
expression = Expression.Call(propertyExpression, method, value);
break;
case FilterType.GreaterThan:
expression = Expression.GreaterThan(propertyExpression, value);
break;
case FilterType.Equals:
expression = Expression.Equal(propertyExpression, value);
break;
default:
throw new ArgumentException("Filter Type could not be determined");
}
// Execute the expression against Query.
var methodCallExpression = Expression.Call(
typeof (Queryable),
"Where",
new[] { Query.ElementType },
Query.Expression,
Expression.Lambda<Func<T, bool>>(expression, new[] { nameExpression }));
// Filter the current Query data.
Query = Query.Provider.CreateQuery<T>(methodCallExpression);
return this;
}
Lo que sucede aquí es el valor constante de la expresión se convierte en el tipo de predicado. Para mayor claridad este método se llama por:
var paramsData = new NameValueCollection { { "CreatedOn", DateTime.Today.ToString() } };
var model = m_data.ToPagedList(new ViewDataDictionary(), paramsData, 1, 10, null, x => x.LastName)
.Filters(Criteria<TrainerProfile>.New(x => x.CreatedOn, FilterType.GreaterThan))
.Setup();
Este código se basa MVC 3, por lo tanto, algunos de los ParamsData [ ""] que es (Request.Params).
Esto suena como un posible error en la biblioteca subyacente. El algoritmo de resolución de sobrecarga debe tomar una T no anulable y una T anulable y elegir la versión del operador levantada a anulable. ¿Puedes publicar una reproducción pequeña, simple y autónoma del problema? También necesitaré el número de versión del compilador que estás usando. Luego puedo pasarlo a los desarrolladores y probadores responsables de esa función. Si prefiere enviarme un correo electrónico directamente a mí, hay un enlace "contácteme" en mi blog, blogs.msdn.com/ericlippert. ¡Gracias! –
Oh alegría :(no es lo que realmente quería escuchar, te envié un correo electrónico con una muestra –
Muestra tu consulta y menciona qué proveedor estás usando. –