开发者

Linq.Dyanmic GroupJoin implementation

I am working on creating an Extension Method in the Linq.Dynamic project for GroupJoin. But, for some reason it will not run. The signatures seem to match.

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

This code gives me the following error:

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.

In looking at the results of each piece they seem to match: Writing the follwing GroupJoin:

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

I get the debug of:

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

With the following GroupJoin:

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

Then looking at the debug:

.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 #开发者_C百科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
    }
}

The only thing different is List<T> compared to IEnumerable. But List<T> is IEnumerable. The error reads like the signature is wrong. I just can't figure it out.

Any incite would be great.


In this statement:

man.Contacts.GroupJoin

What is the Type of Contacts? Does it inherit from IQueryable? or IQueryable<T>?

My guess is it is an IQueryable<T>. This error:

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.

Is saying that there are type arguments being provided in the method call, and it can't find a generic method 'GroupJoin' that is compatible with these type arguments. The 'GroupJoin' that you wrote is expecting no type arguments, so you will probably have to modify it to expect one or some.

I think it is also possible that the problem is with the second parameter, where man.ContactAddresses is passed in. But Contacts is the first place I'd look.


I know it might be too late but I found this as answer:

Try using:

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

It worked for me.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜