sqlquery query multiple framework consulta columns async c# .net expression entity-framework-6 iqueryable

multiple - Problemas para construir una Expresión IQueryable de C#EntityFramework



sqlquery c# entity framework (2)

Aquí hay un método que te permitirá componer expresiones; es decir, puede usar la salida de una expresión como la entrada de otra, creando una nueva expresión que toma la entrada que toma la primera y la que la segunda toma:

public static Expression<Func<TFirstParam, TResult>> Compose<TFirstParam, TIntermediate, TResult>( this Expression<Func<TFirstParam, TIntermediate>> first, Expression<Func<TIntermediate, TResult>> second) { var param = Expression.Parameter(typeof(TFirstParam), "param"); var newFirst = first.Body.Replace(first.Parameters[0], param); var newSecond = second.Body.Replace(second.Parameters[0], newFirst); return Expression.Lambda<Func<TFirstParam, TResult>>(newSecond, param); }

Que usa el siguiente método para reemplazar una expresión por otra:

internal class ReplaceVisitor : ExpressionVisitor { private readonly Expression from, to; public ReplaceVisitor(Expression from, Expression to) { this.from = from; this.to = to; } public override Expression Visit(Expression node) { return node == from ? to : base.Visit(node); } } public static Expression Replace(this Expression expression, Expression searchEx, Expression replaceEx) { return new ReplaceVisitor(searchEx, replaceEx).Visit(expression); }

Esto te permite escribir:

public static IQueryable<TSource> Search<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, string>> getValueExpression, string searchOption, string searchValue) { var predicate = getValueExpression.Compose(value => value == searchValue); return source.Where(predicate); }

Así que estoy intentando construir una expresión de búsqueda de semi complicación, pero estoy atrapado tratando de crear uno básico. Las expresiones que se utilizan para getValueExpression tienen el siguiente aspecto:

x => x.PropertyA != null ? x.PropertyA.ToShortDateString() : "" //nullable datetime x => x.PropertyB //string property x => x.PropertyC != null x.PropertyC.ToString() : "" //nullable int

Aquí está mi código de función, actualmente errores cuando getValueExpression es de tipo Func que no se puede comparar con una cadena, lo cual tiene mucho sentido y entiendo por qué es así, pero estoy teniendo problemas para averiguar cómo hacer una expresión que obtiene el valor de getValueExpression para comparar con el valor que se busca. Cualquier ayuda o pistas en la dirección correcta sería muy apreciada.

public static IQueryable<TSource> Search<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, string>> getValueExpression, string searchOption, string searchValue) { var searchValueExpression = Expression.Constant(searchValue); var comparisonExpression = Expression.Equal(getValueExpression, searchValueExpression); var lambdaExpression = Expression.Lambda<Func<TSource, bool>>(comparisonExpression); return source.Where(lambdaExpression); }

Intenté cosas similares como esta, pero me encontré con una falla con la excepción de importe de argumentos incorrectos:

var getValueExpressionValue = Expression.Call(getValueExpression.Compile().Method, parameterValueExpression);


Aquí sabrás como podrás hacerlo :

public static IQueryable<TSource> Search<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, string>> getValueExpression, string searchOption, string searchValue) { // const searchValue var searchValueExpression = Expression.Constant(searchValue); // parameter x var parameterExpression = Expression.Parameter(typeof(TSource)); // func(x) var parameterGetValueExpression = Expression.Invoke(getValueExpression, parameterExpression); // func(x) == searchValue var comparisonExpression = Expression.Equal(parameterGetValueExpression, searchValueExpression); // x => func(x) == searchValue var lambdaExpression = Expression.Lambda<Func<TSource, bool>>(comparisonExpression, parameterExpression); return source.Where(lambdaExpression); }