我正在为GroupJoin在Linq.Dynamic项目中创建扩展方法。但是,由于某种原因它不会运行。签名似乎匹配。
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));
}
此代码给出了以下错误:
类型'System.Linq.Queryable'上没有泛型方法'GroupJoin'与提供的类型参数和参数兼容。如果方法是非泛型的,则不应提供类型参数。
在查看每件作品的结果时,他们似乎匹配: 写下以下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 });
我得到了调试:
.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)
}
使用以下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)");
然后查看调试:
.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
}
}
与IEnumerable相比,唯一不同的是List<T>
。但是List<T>
是IEnumerable。
错误读起来就像签名错误。我只是想不出来。
任何煽动都会很棒。
答案 0 :(得分:0)
在此声明中:
man.Contacts.GroupJoin
Contacts
的类型是什么?它是否继承自IQueryable
?还是IQueryable<T>
?
我的猜测是IQueryable<T>
。这个错误:
类型上没有通用方法'GroupJoin' 'System.Linq.Queryable'兼容 使用提供的类型参数和 参数。不应该有类型参数 如果方法是非通用的,则提供。
是说在方法调用中提供了类型参数,并且它找不到与这些类型参数兼容的泛型方法“GroupJoin”。您编写的'GroupJoin'期望没有类型参数,因此您可能需要修改它以期望一个或一些。
我认为问题也可能出在传递man.ContactAddresses
的第二个参数上。但Contacts
是我看的第一个地方。
答案 1 :(得分:0)
我知道这可能为时已晚,但我发现这是答案:
尝试使用:
Type enumType = typeof(IEnumerable<>).MakeGenericType(inner.AsQueryable().ElementType);
它对我有用。