2010-08-11 79 views
1

我正在爲GroupJoin的Linq.Dynamic項目創建擴展方法。但是,由於某種原因,它不會運行。簽名似乎匹配。Linq.Dyanmic GroupJoin implementation

public static IQueryable GroupJoin(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); 
    Type enumType = GetList(inner.AsQueryable().ElementType).GetType(); 

    LambdaExpression innerSelectorLambda = DynamicExpression.ParseLambda(inner.AsQueryable().ElementType, null, innerSelector, values); 

    ParameterExpression[] parameters = new ParameterExpression[] { 
    Expression.Parameter(outer.ElementType, "outer"), Expression.Parameter(enumType, "inner") }; 
    LambdaExpression resultsSelectorLambda = DynamicExpression.ParseLambda(parameters, null, resultsSelector, values);   

    return outer.Provider.CreateQuery(
     Expression.Call(
      typeof(Queryable), "GroupJoin", 
      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))); 
} 

public static IEnumerable GetList(System.Type type) 
{ 
    return (IEnumerable)Activator.CreateInstance(typeof(List<>).MakeGenericType(type)); 
} 

此代碼給我下面的錯誤:

No generic method 'GroupJoin' on type 'System.Linq.Queryable' is compatible with the supplied type arguments and arguments. No type arguments should be provided if the method is non-generic.

在看着每片的結果,他們似乎一致: 編寫follwing羣組加入:

man.Contacts.GroupJoin(man.ContactAddresses, param_0 => param_0.ContactId, param_0 => param_0.ContactId, 
       (outer, inner) => new { ContactId = outer.ContactId, FirstName = outer.FirstName, LastName = outer.LastName, MI = outer.MiddleInitial, ContactAddresses = inner }); 

我得到調試:

.Call System.Linq.Queryable.GroupJoin(
.Constant<IdeaBlade.EntityModel.EntityQueryProxy`1[LOC.AMP.Data.DomainModel.Contact]>(IdeaBlade.EntityModel.EntityQueryProxy`1[LOC.AMP.Data.DomainModel.Contact]), .Constant<IdeaBlade.EntityModel.EntityQueryProxy`1[LOC.AMP.Data.DomainModel.ContactAddress]>(IdeaBlade.EntityModel.EntityQueryProxy`1[LOC.AMP.Data.DomainModel.ContactAddress]), 
'(.Lambda #Lambda1<System.Func`2[LOC.AMP.Data.DomainModel.Contact,System.Int64]>), 
'(.Lambda #Lambda2<System.Func`2[LOC.AMP.Data.DomainModel.ContactAddress,System.Int64]>), 
'(.Lambda #Lambda3<System.Func`3[LOC.AMP.Data.DomainModel.Contact,System.Collections.Generic.IEnumerable`1[LOC.AMP.Data.DomainModel.ContactAddress], <>f__AnonymousType0`5[System.Int64,System.String,System.String,System.String,System.Collections.Generic.IEnumerable`1[LOC.AMP.Data.DomainModel.ContactAddress]]]>)) 
.Lambda #Lambda1<System.Func`2[LOC.AMP.Data.DomainModel.Contact,System.Int64]>(LOC.AMP.Data.DomainModel.Contact $param_0) 
{ 
    $param_0.ContactId 
}  
.Lambda #Lambda2<System.Func`2[LOC.AMP.Data.DomainModel.ContactAddress,System.Int64]>(LOC.AMP.Data.DomainModel.ContactAddress $param_0) 
{ 
    $param_0.ContactId 
}  
.Lambda 
    #Lambda3<System.Func`3 
    [ 
     LOC.AMP.Data.DomainModel.Contact, System.Collections.Generic.IEnumerable`1[LOC.AMP.Data.DomainModel.ContactAddress], 
     <>f__AnonymousType0`5 
     [ 
      System.Int64,System.String,System.String,System.String, System.Collections.Generic.IEnumerable`1 
      [ 
       LOC.AMP.Data.DomainModel.ContactAddress 
      ] 
     ] 
    ]> 
    (LOC.AMP.Data.DomainModel.Contact $outer, System.Collections.Generic.IEnumerable`1 
     [LOC.AMP.Data.DomainModel.ContactAddress] $inner) 

    { 
    .New <>f__AnonymousType0`5[System.Int64,System.String,System.String,System.String,System.Collections.Generic.IEnumerable`1[LOC.AMP.Data.DomainModel.ContactAddress]](
     $outer.ContactId, 
     $outer.FirstName, 
     $outer.LastName, 
     $outer.MiddleInitial, 
     $inner) 
} 

用下面的羣組加入:

man.Contacts.GroupJoin(man.ContactAddresses, "ContactId", "ContactId", "new (outer.ContactId as ContactId, outer.FirstName as FirstName, outer.LastName as LastName, outer.MiddleInitial as MI, inner as ContactAddresses)"); 

然後看着調試:

.Call GroupJoin (
{value(IdeaBlade.EntityModel.EntityQueryProxy'1[LOC.AMP.Data.DomainModel.Contact])}, {value(IdeaBlade.EntityModel.EntityQueryProxy'1[LOC.AMP.Data.DomainModel.ContactAddress])}, 
'(.Lambda #Lambda1<System.Func'2[LOC.AMP.Data.DomainModel.Contact,System.Int64]>), 
'(.Lambda #Lambda1<System.Func'2[LOC.AMP.Data.DomainModel.ContactAddress,System.Int64]>), 
'(.Lambda #Lambda1<System.Func'3[LOC.AMP.Data.DomainModel.Contact,System.Collections.Generic.List`1[LOC.AMP.Data.DomainModel.ContactAddress],DynamicClass1]>) 

//ContactId 
.Lambda #Lambda1<System.Func'2[LOC.AMP.Data.DomainModel.Contact,System.Int64]>(LOC.AMP.Data.DomainModel.Contact $var1) 
{ 
    $var1.ContactId 
} 

//CA.ContactId 
.Lambda #Lambda1<System.Func'2[LOC.AMP.Data.DomainModel.ContactAddress,System.Int64]>(LOC.AMP.Data.DomainModel.ContactAddress $var1) 
{ 
    $var1.ContactId 
} 
//Dynamic Result 
.Lambda #Lambda1<System.Func`3[LOC.AMP.Data.DomainModel.Contact,System.Collections.Generic.List`1[LOC.AMP.Data.DomainModel.ContactAddress],DynamicClass1]>(
    LOC.AMP.Data.DomainModel.Contact $outer, 
    System.Collections.Generic.List`1[LOC.AMP.Data.DomainModel.ContactAddress] $inner) 
    { 
    .New DynamicClass1(){ 
     ContactId = $outer.ContactId, 
     FirstName = $outer.FirstName, 
     LastName = $outer.LastName, 
     MI = $outer.MiddleInitial, 
     ContactAddresses = $inner 
    } 
} 

唯一不同的是List<T>相比IEnumerable的。但List<T>是IEnumerable。 錯誤讀取像簽名是錯誤的。我無法弄清楚。

任何煽動都會很好。

回答

0

在此聲明:

man.Contacts.GroupJoin 

什麼是Contacts的類型?它是否繼承IQueryable?或IQueryable<T>?我的猜測是IQueryable<T>。此錯誤:

No generic method 'GroupJoin' on type 'System.Linq.Queryable' is compatible with the supplied type arguments and arguments. No type arguments should be provided if the method is non-generic.

是說,有方法調用所提供類型的參數,它無法找到一個通用的方法「羣組加入」是具有這些類型的參數兼容。你寫的'GroupJoin'預計是沒有類型參數,所以你可能需要修改它以期待一個或者一些。

我認爲這也可能是第二個參數,其中man.ContactAddresses傳入。但Contacts是我看的第一個地方。

0

我知道這可能爲時已晚,但我發現這是答案:

嘗試使用:

Type enumType = typeof(IEnumerable<>).MakeGenericType(inner.AsQueryable().ElementType); 

它爲我工作。