scottgu query dinamico create c# .net linq linq-to-sql dynamic-linq

dinamico - query dynamic object c#



¿Cómo hago una unión externa izquierda con Dynamic Linq? (1)

Añadir void DefaultIfEmpty(); interface IEnumerableSignatures

Entonces use

public static object DefaultIfEmpty(this IQueryable source) { if (source == null) throw new ArgumentNullException("source"); return source.Provider.Execute( Expression.Call( typeof(Queryable), "DefaultIfEmpty", new Type[] { source.ElementType }, source.Expression)); }

Entonces tienes una llamada como

var qry = Foo.GroupJoin(Bar, "outer.Id", "inner.Id", "new(outer.Id as Foo, group as Bars)").SelectMany("Bars.DefaultIfEmpty()", "new(outer.Foo as Foo, inner as Bar)");

Estoy tratando de imitar la combinación externa izquierda here pero usando métodos de extensión linq dinámicos. Lo que tengo:

public static IQueryable SelectMany(this IQueryable source, string selector, string resultsSelector, params object[] values) { if (source == null) throw new ArgumentNullException("source"); if (selector == null) throw new ArgumentNullException("selector"); // Parse the lambda LambdaExpression lambda = DynamicExpression.ParseLambda( source.ElementType, null, selector, values); // Fix lambda by recreating to be of correct Func<> type in case // the expression parsed to something other than IEnumerable<T>. // For instance, a expression evaluating to List<T> would result // in a lambda of type Func<T, List<T>> when we need one of type // an Func<T, IEnumerable<T> in order to call SelectMany(). Type inputType = source.Expression.Type.GetGenericArguments()[0]; Type resultType = lambda.Body.Type.GetGenericArguments()[0]; Type enumerableType = typeof(IEnumerable<>).MakeGenericType(resultType); Type delegateType = typeof(Func<,>).MakeGenericType(inputType, enumerableType); lambda = Expression.Lambda(delegateType, lambda.Body, lambda.Parameters); ParameterExpression[] parameters = new ParameterExpression[] { Expression.Parameter(source.ElementType, "outer"), Expression.Parameter(resultType, "inner") }; LambdaExpression resultsSelectorLambda = DynamicExpression.ParseLambda( parameters, null, resultsSelector, values); // Create the new query return source.Provider.CreateQuery(Expression.Call(typeof(Queryable), "SelectMany", new Type[] { source.ElementType, resultType, resultsSelectorLambda.Body.Type }, source.Expression, Expression.Quote(lambda), Expression.Quote(resultsSelectorLambda))); }

y:

public static IQueryable GroupJoin(this IQueryable outer, IEnumerable inner, string outerKeySelector, string innerKeySelector, string resultSelector, params object[] values) { Type innerElementType = inner.AsQueryable().ElementType; var outerParameter = Expression.Parameter(outer.ElementType, "outer"); var innerParameter = Expression.Parameter(innerElementType, "inner"); var groupParameter = Expression.Parameter(typeof(IEnumerable<>) .MakeGenericType(innerElementType), "group"); var outerLambda = DynamicExpression.ParseLambda(new[] { outerParameter }, null, outerKeySelector, values); var innerLambda = DynamicExpression.ParseLambda(new[] { innerParameter }, outerLambda.Body.Type, innerKeySelector, values); var resultLambda = DynamicExpression.ParseLambda(new[] { outerParameter, groupParameter }, null, resultSelector, values); return outer.Provider.CreateQuery(Expression.Call(typeof(Queryable), "GroupJoin", new[] { outer.ElementType, innerElementType, outerLambda.Body.Type, resultLambda.Body.Type }, outer.Expression, Expression.Constant(inner), Expression.Quote(outerLambda), Expression.Quote(innerLambda), Expression.Quote(resultLambda))); }

Sin embargo, cuando me caigo es con DefaultIfEmpty dentro de SelectMany