在LINQ扩展方法中键入参数错误

时间:2011-01-26 05:22:08

标签: linq entity-framework arguments

我写了一个LINQ扩展来加入2个表

public static IEnumerable<ObjectDetail<TLeft, string>> ToDetail<TLeft, TRight, TKey>(this IEnumerable<TLeft> left, IEnumerable<TRight> right, Func<TLeft, TKey> leftProperty, Func<TRight, TKey> rightProperty, Func<TRight, TKey> keyProperty, Func<TRight, TKey> valueProperty, string keySelector)
        {
            return (from l in left
                    join r in right on leftProperty(l) equals rightProperty(r) into one
                    select new
                    {
                        l,
                        one
                    }).AsEnumerable().Select(q => new ObjectDetail<TLeft, string>
                    {
                        Item = q.l,
                        Meta = q.one.Where(m => keySelector.Contains(keyProperty(m).ToString())).ToDictionary(m => keyProperty(m).ToString(), m => valueProperty(m).ToString())
                    });
        }

编译器很好地理解扩展,但是当我尝试编写

var result = left.ToDetail(right, l => l.ID, r => r.ID, r => r.Key, r => r.Value, "Key");

我收到以下错误:

  

方法的类型参数   .ToDetail(System.Collections.Generic.IEnumerable,   System.Collections.Generic.IEnumerable,   System.Func,   System.Func,   System.Func,   System.Func,string)'   无法从使用中推断出来。尝试   指定类型参数   明确地

然后我尝试从扩展中删除keyProperty和valueProperty参数,它运行良好,没有任何错误。我不知道为什么,也许编译器混淆了,无法确定具有相同类型的参数?

任何帮助都将不胜感激!

1 个答案:

答案 0 :(得分:1)

在函数声明中,对rightPropertykeyPropertyvalueProperty参数使用相同的函数类型,因此这两个函数都应该具有类型Func<TRight, TKey>

这意味着当您调用该函数时,r.IDr.Keyr.Value的类型必须相同(以便C#编译器可以推断出TKey从这两个类型参数)。我的猜测是,在你的例子中,这三个中至少有一个是不同的(可能是ID)。

(除此之外,由于您使用valueSelector方法将keySelectorToString的结果转换为字符串,因此您可能无需使用泛型类型 - a函数返回object应该可以解决问题。)