Como criar um método de extensão de junit LINQ dinâmica

Havia uma biblioteca de methods de extensões LINQ dinâmicas lançadas como uma amostra com o Visual Studio 2008 . Eu gostaria de estendê-lo com um método de junit. O código abaixo falha com uma exceção de correspondência de falta do parâmetro no tempo de execução. Onde está o problema?

public static IQueryable Join(this IQueryable outer, IEnumerable inner, string outerSelector, string innerSelector, string resultsSelector, params object[] values) { if (inner == null) throw new ArgumentNullException("inner"); if (outerSelector == null) throw new ArgumentNullException("outerSelector"); if (innerSelector == null) throw new ArgumentNullException("innerSelector"); if (resultsSelector == null) throw new ArgumentNullException("resultsSelctor"); LambdaExpression outerSelectorLambda = DynamicExpression.ParseLambda(outer.ElementType, null, outerSelector, values); LambdaExpression innerSelectorLambda = DynamicExpression.ParseLambda(inner.AsQueryable().ElementType, null, innerSelector, values); ParameterExpression[] parameters = new ParameterExpression[] { Expression.Parameter(outer.ElementType, "outer"), Expression.Parameter(inner.AsQueryable().ElementType, "inner") }; LambdaExpression resultsSelectorLambda = DynamicExpression.ParseLambda(parameters, null, resultsSelector, values); return outer.Provider.CreateQuery( Expression.Call( typeof(Queryable), "Join", new Type[] { outer.ElementType, inner.AsQueryable().ElementType, outerSelectorLambda.Body.Type, innerSelectorLambda.Body.Type, resultsSelectorLambda.Body.Type }, outer.Expression, inner.AsQueryable().Expression, Expression.Quote(outerSelectorLambda), Expression.Quote(innerSelectorLambda), Expression.Quote(resultsSelectorLambda)) ); } 

Eu mesmo consertei isso agora. Foi um erro de aluno passando muitos parâmetros para a chamada CreateQuery (…). Cole o seguinte código no arquivo Dynamic.cs dentro da class DynamicQueryable para um método dynamic de extensão de associação. Você pode encontrar a fonte do projeto de amostra DynamicQuery em http://code.msdn.microsoft.com/csharpsamples .
Apreciar.

  public static IQueryable Join(this IQueryable outer, IEnumerable inner, string outerSelector, string innerSelector, string resultsSelector, params object[] values) { if (inner == null) throw new ArgumentNullException("inner"); if (outerSelector == null) throw new ArgumentNullException("outerSelector"); if (innerSelector == null) throw new ArgumentNullException("innerSelector"); if (resultsSelector == null) throw new ArgumentNullException("resultsSelctor"); LambdaExpression outerSelectorLambda = DynamicExpression.ParseLambda(outer.ElementType, null, outerSelector, values); LambdaExpression innerSelectorLambda = DynamicExpression.ParseLambda(inner.AsQueryable().ElementType, null, innerSelector, values); ParameterExpression[] parameters = new ParameterExpression[] { Expression.Parameter(outer.ElementType, "outer"), Expression.Parameter(inner.AsQueryable().ElementType, "inner") }; LambdaExpression resultsSelectorLambda = DynamicExpression.ParseLambda(parameters, null, resultsSelector, values); return outer.Provider.CreateQuery( Expression.Call( typeof(Queryable), "Join", new Type[] {outer.ElementType, inner.AsQueryable().ElementType, outerSelectorLambda.Body.Type, resultsSelectorLambda.Body.Type }, outer.Expression, inner.AsQueryable().Expression, Expression.Quote(outerSelectorLambda), Expression.Quote(innerSelectorLambda), Expression.Quote(resultsSelectorLambda))); } //The generic overload. public static IQueryable Join(this IQueryable outer, IEnumerable inner, string outerSelector, string innerSelector, string resultsSelector, params object[] values) { return (IQueryable)Join((IQueryable)outer, (IEnumerable)inner, outerSelector, innerSelector, resultsSelector, values); } 

Você pode instalar o pacote nuget de System.Linq.Dynamic.Core – https://github.com/StefH/System.Linq.Dynamic.Core

Isso tem o método de associação implementado junto com vários outros methods auxiliares.

Usando esta biblioteca você pode fazer uma simples junit da seguinte maneira

myContext.TableA.Join(myContext.TableB,'Id','TableAId','outer',null)

no seletor de resultados outer e inner são palavras-chave para acessar o resultado da junit.

Usar uma chave com várias propriedades e / ou selecionar um resultado com várias propriedades pode ser feito da seguinte maneira

myContext.TableA.Join(myContext.TableB,'new (Id as key1,Code as key2)','new (TableAId as key1,AnotherCol as key2)','new(outer.Id,inner.Desc)',null)

Aqui está um código de exemplo mostrando uma junit em várias colunas. Usando um datatable e datarows você precisa sempre acessar campos através do indexador.

  DataTable t1 = new DataTable(); t1.Columns.Add("FundId", typeof(int)); t1.Columns.Add("Date", typeof(DateTime)); t1.Columns.Add("CodeA", typeof(string)); t1.Rows.Add(1, new DateTime(2010, 01, 01), "A1"); t1.Rows.Add(2, new DateTime(2010, 01, 01), "A2"); t1.Rows.Add(3, new DateTime(2010, 01, 01), "A3"); DataTable t2 = new DataTable(); t2.Columns.Add("FundId", typeof(int)); t2.Columns.Add("Date", typeof(DateTime)); t2.Columns.Add("CodeB", typeof(string)); t2.Rows.Add(1, new DateTime(2010, 01, 01), "B1"); t2.Rows.Add(2, new DateTime(2010, 01, 01), "B2"); t2.Rows.Add(3, new DateTime(2010, 01, 01), "B3"); IQueryable outerTable = t1.AsEnumerable().AsQueryable(); IEnumerable innerTable = t2.AsEnumerable(); var query = outerTable.Join ( innerTable, "new(get_Item(0) as FundId, get_Item(1) as Date)", "new(get_Item(0) as FundId, get_Item(1) as Date)", "new(outer.get_Item(0) as FundId, outer.get_Item(2) as CodeA, inner.get_Item(2) as CodeB)" );