如何使用Dynamic Linq进行左外连接?

我试图在这里模仿左外连接,但使用动态linq扩展方法。 是)我有的:

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. // For instance, a expression evaluating to List would result // in a lambda of type Func<T, List> when we need one of type // an Func<T, IEnumerable 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))); } 

和:

 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))); } 

但是我失败的地方是SelectManyDefaultIfEmpty

添加void DefaultIfEmpty(); interface IEnumerableSignatures

然后用

 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)); } 

然后你有一个像这样的电话

 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)");