diff --git a/src/EFCore/Query/QueryableMethods.cs b/src/EFCore/Query/QueryableMethods.cs
index 96a0bcf81a5..1df5679098f 100644
--- a/src/EFCore/Query/QueryableMethods.cs
+++ b/src/EFCore/Query/QueryableMethods.cs
@@ -16,20 +16,11 @@ namespace Microsoft.EntityFrameworkCore.Query
///
public static class QueryableMethods
{
- ///
- /// The for
- ///
- public static MethodInfo AsQueryable { get; }
+ //public static MethodInfo AggregateWithoutSeed { get; }
- ///
- /// The for
- ///
- public static MethodInfo Cast { get; }
+ //public static MethodInfo AggregateWithSeedWithoutSelector { get; }
- ///
- /// The for
- ///
- public static MethodInfo OfType { get; }
+ //public static MethodInfo AggregateWithSeedSelector { get; }
///
/// The for
@@ -43,34 +34,33 @@ public static class QueryableMethods
///
/// The for
- ///
+ ///
///
public static MethodInfo AnyWithPredicate { get; }
- ///
- /// The for
- ///
- public static MethodInfo Contains { get; }
+ //public static MethodInfo AsQueryableNonGeneric { get; }
///
- /// The for
+ /// The for
///
- public static MethodInfo Concat { get; }
+ public static MethodInfo AsQueryable { get; }
///
- /// The for
+ /// The for
///
- public static MethodInfo Except { get; }
+ public static MethodInfo Cast { get; }
///
- /// The for
+ /// The for
///
- public static MethodInfo Intersect { get; }
+ public static MethodInfo Concat { get; }
///
- /// The for
+ /// The for
///
- public static MethodInfo Union { get; }
+ public static MethodInfo Contains { get; }
+
+ //public static MethodInfo ContainsWithComparer { get; }
///
/// The for
@@ -79,39 +69,26 @@ public static class QueryableMethods
///
/// The for
- ///
+ ///
///
public static MethodInfo CountWithPredicate { get; }
///
- /// The for
- ///
- public static MethodInfo LongCountWithoutPredicate { get; }
-
- ///
- /// The for
- ///
- public static MethodInfo LongCountWithPredicate { get; }
-
- ///
- /// The for
+ /// The for
///
- public static MethodInfo MinWithSelector { get; }
+ public static MethodInfo DefaultIfEmptyWithoutArgument { get; }
///
- /// The for
+ /// The for
///
- public static MethodInfo MinWithoutSelector { get; }
+ public static MethodInfo DefaultIfEmptyWithArgument { get; }
///
- /// The for
+ /// The for
///
- public static MethodInfo MaxWithSelector { get; }
+ public static MethodInfo Distinct { get; }
- ///
- /// The for
- ///
- public static MethodInfo MaxWithoutSelector { get; }
+ //public static MethodInfo DistinctWithComparer { get; }
///
/// The for
@@ -123,6 +100,13 @@ public static class QueryableMethods
///
public static MethodInfo ElementAtOrDefault { get; }
+ ///
+ /// The for
+ ///
+ public static MethodInfo Except { get; }
+
+ //public static MethodInfo ExceptWithComparer { get; }
+
///
/// The for
///
@@ -144,24 +128,63 @@ public static class QueryableMethods
public static MethodInfo FirstOrDefaultWithPredicate { get; }
///
- /// The for
+ /// The for
///
- public static MethodInfo SingleWithoutPredicate { get; }
+ public static MethodInfo GroupByWithKeySelector { get; }
///
- /// The for
+ /// The for
+ ///
///
- public static MethodInfo SingleWithPredicate { get; }
+ public static MethodInfo GroupByWithKeyElementSelector { get; }
+
+ //public static MethodInfo GroupByWithKeySelectorAndComparer { get; }
+
+ //public static MethodInfo GroupByWithKeyElementSelectorAndComparer { get; }
///
- /// The for
+ /// The for
+ ///
///
- public static MethodInfo SingleOrDefaultWithoutPredicate { get; }
+ public static MethodInfo GroupByWithKeyElementResultSelector { get; }
///
- /// The for
+ /// The for
+ ///
///
- public static MethodInfo SingleOrDefaultWithPredicate { get; }
+ public static MethodInfo GroupByWithKeyResultSelector { get; }
+
+ //public static MethodInfo GroupByWithKeyResultSelectorAndComparer { get; }
+
+ //public static MethodInfo GroupByWithKeyElementResultSelectorAndComparer { get; }
+
+ ///
+ /// The for
+ ///
+ ///
+ public static MethodInfo GroupJoin { get; }
+
+ //public static MethodInfo GroupJoinWithComparer { get; }
+
+ ///
+ /// The for
+ ///
+ public static MethodInfo Intersect { get; }
+
+ //public static MethodInfo IntersectWithComparer { get; }
+
+ ///
+ /// The for
+ ///
+ ///
+ public static MethodInfo Join { get; }
+
+ //public static MethodInfo JoinWithComparer { get; }
///
/// The for
@@ -184,496 +207,642 @@ public static class QueryableMethods
public static MethodInfo LastOrDefaultWithPredicate { get; }
///
- /// The for
- ///
- public static MethodInfo Distinct { get; }
-
- ///
- /// The for
+ /// The for
///
- public static MethodInfo Reverse { get; }
+ public static MethodInfo LongCountWithoutPredicate { get; }
///
- /// The for
+ /// The for
///
- public static MethodInfo Where { get; }
+ public static MethodInfo LongCountWithPredicate { get; }
///
- /// The for
- ///
+ /// The for
///
- public static MethodInfo Select { get; }
+ public static MethodInfo MaxWithoutSelector { get; }
///
- /// The for
+ /// The for
///
- public static MethodInfo Skip { get; }
+ public static MethodInfo MaxWithSelector { get; }
///
- /// The for
+ /// The for
///
- public static MethodInfo Take { get; }
+ public static MethodInfo MinWithoutSelector { get; }
///
- /// The for
+ /// The for
///
- public static MethodInfo SkipWhile { get; }
+ public static MethodInfo MinWithSelector { get; }
///
- /// The for
+ /// The for
///
- public static MethodInfo TakeWhile { get; }
+ public static MethodInfo OfType { get; }
///
/// The for
///
public static MethodInfo OrderBy { get; }
+ //public static MethodInfo OrderByWithComparer { get; }
+
///
/// The for
///
///
public static MethodInfo OrderByDescending { get; }
+ //public static MethodInfo OrderByDescendingWithComparer { get; }
+
+ ///
+ /// The for
+ ///
+ public static MethodInfo Reverse { get; }
+
///
/// The for
- ///
+ ///
///
- public static MethodInfo ThenBy { get; }
+ public static MethodInfo Select { get; }
+
+ //public static MethodInfo SelectWithOrdinal { get; }
///
/// The for
- ///
+ ///
///
- public static MethodInfo ThenByDescending { get; }
+ public static MethodInfo SelectManyWithoutCollectionSelector { get; }
+
+ //public static MethodInfo SelectManyWithoutCollectionSelectorOrdinal { get; }
///
- /// The for
+ /// The for
+ ///
///
- public static MethodInfo DefaultIfEmptyWithoutArgument { get; }
+ public static MethodInfo SelectManyWithCollectionSelector { get; }
+
+ //public static MethodInfo SelectManyWithCollectionSelectorOrdinal { get; }
+
+ //public static MethodInfo SequenceEqual { get; }
+
+ //public static MethodInfo SequenceEqualWithComparer { get; }
///
- /// The for
+ /// The for
///
- public static MethodInfo DefaultIfEmptyWithArgument { get; }
+ public static MethodInfo SingleWithoutPredicate { get; }
///
- /// The for
- ///
+ /// The for
///
- public static MethodInfo Join { get; }
+ public static MethodInfo SingleWithPredicate { get; }
///
- /// The for
- ///
+ /// The for
///
- public static MethodInfo GroupJoin { get; }
+ public static MethodInfo SingleOrDefaultWithoutPredicate { get; }
///
- /// The for
- ///
+ /// The for
///
- public static MethodInfo SelectManyWithCollectionSelector { get; }
+ public static MethodInfo SingleOrDefaultWithPredicate { get; }
///
- /// The for
- ///
+ /// The for
///
- public static MethodInfo SelectManyWithoutCollectionSelector { get; }
+ public static MethodInfo Skip { get; }
///
- /// The for
+ /// The for
///
- public static MethodInfo GroupByWithKeySelector { get; }
+ public static MethodInfo SkipWhile { get; }
+
+ //public static MethodInfo SkipWhileOrdinal { get; }
///
- /// The for
- ///
+ /// The for
///
- public static MethodInfo GroupByWithKeyElementSelector { get; }
+ public static MethodInfo Take { get; }
+
+ ///
+ /// The for
+ ///
+ public static MethodInfo TakeWhile { get; }
+
+ //public static MethodInfo TakeWhileOrdinal { get; }
///
/// The for
- ///
+ ///
///
- public static MethodInfo GroupByWithKeyElementResultSelector { get; }
+ public static MethodInfo ThenBy { get; }
+
+ //public static MethodInfo ThenByWithComparer { get; }
///
/// The for
- ///
+ ///
///
- public static MethodInfo GroupByWithKeyResultSelector { get; }
+ public static MethodInfo ThenByDescending { get; }
+
+ //public static MethodInfo ThenByDescendingWithComparer { get; }
///
- /// Checks whether or not the given is one of the without a selector.
+ /// The for
+ ///
+ public static MethodInfo Union { get; }
+
+ //public static MethodInfo UnionWithComparer { get; }
+
+ ///
+ /// The for
+ ///
+ public static MethodInfo Where { get; }
+
+ //public static MethodInfo WhereOrdinal { get; }
+
+ //public static MethodInfo Zip { get; }
+
+ ///
+ /// Checks whether or not the given is one of the without a selector.
///
/// The method to check.
/// if the method matches; otherwise.
- public static bool IsSumWithoutSelector([NotNull] MethodInfo methodInfo)
+ public static bool IsAverageWithoutSelector([NotNull] MethodInfo methodInfo)
{
Check.NotNull(methodInfo, nameof(methodInfo));
- return SumWithoutSelectorMethods.Values.Contains(methodInfo);
+ return AverageWithoutSelectorMethods.Values.Contains(methodInfo);
}
///
- /// Checks whether or not the given is one of the with a selector.
+ /// Checks whether or not the given is one of the with a selector.
///
/// The method to check.
/// if the method matches; otherwise.
- public static bool IsSumWithSelector([NotNull] MethodInfo methodInfo)
+ public static bool IsAverageWithSelector([NotNull] MethodInfo methodInfo)
{
Check.NotNull(methodInfo, nameof(methodInfo));
return methodInfo.IsGenericMethod
- && SumWithSelectorMethods.Values.Contains(methodInfo.GetGenericMethodDefinition());
+ && AverageWithSelectorMethods.Values.Contains(methodInfo.GetGenericMethodDefinition());
}
///
- /// Checks whether or not the given is one of the without a selector.
+ /// Checks whether or not the given is one of the without a selector.
///
/// The method to check.
/// if the method matches; otherwise.
- public static bool IsAverageWithoutSelector([NotNull] MethodInfo methodInfo)
+ public static bool IsSumWithoutSelector([NotNull] MethodInfo methodInfo)
{
Check.NotNull(methodInfo, nameof(methodInfo));
- return AverageWithoutSelectorMethods.Values.Contains(methodInfo);
+ return SumWithoutSelectorMethods.Values.Contains(methodInfo);
}
///
- /// Checks whether or not the given is one of the with a selector.
+ /// Checks whether or not the given is one of the with a selector.
///
/// The method to check.
/// if the method matches; otherwise.
- public static bool IsAverageWithSelector([NotNull] MethodInfo methodInfo)
+ public static bool IsSumWithSelector([NotNull] MethodInfo methodInfo)
{
Check.NotNull(methodInfo, nameof(methodInfo));
return methodInfo.IsGenericMethod
- && AverageWithSelectorMethods.Values.Contains(methodInfo.GetGenericMethodDefinition());
+ && SumWithSelectorMethods.Values.Contains(methodInfo.GetGenericMethodDefinition());
}
///
- /// Returns the for the method without a selector for the given type.
+ /// Returns the for the method without a selector for the given type.
///
/// The generic type of the method to create.
/// The .
- public static MethodInfo GetSumWithoutSelector([NotNull] Type type)
+ public static MethodInfo GetAverageWithoutSelector([NotNull] Type type)
{
Check.NotNull(type, nameof(type));
- return SumWithoutSelectorMethods[type];
+ return AverageWithoutSelectorMethods[type];
}
///
- /// Returns the for the method with a selector for the given type.
+ /// Returns the for the method with a selector for the given type.
///
/// The generic type of the method to create.
/// The .
- public static MethodInfo GetSumWithSelector([NotNull] Type type)
+ public static MethodInfo GetAverageWithSelector([NotNull] Type type)
{
Check.NotNull(type, nameof(type));
- return SumWithSelectorMethods[type];
+ return AverageWithSelectorMethods[type];
}
///
- /// Returns the for the method without a selector for the given type.
+ /// Returns the for the method without a selector for the given type.
///
/// The generic type of the method to create.
/// The .
- public static MethodInfo GetAverageWithoutSelector([NotNull] Type type)
+ public static MethodInfo GetSumWithoutSelector([NotNull] Type type)
{
Check.NotNull(type, nameof(type));
- return AverageWithoutSelectorMethods[type];
+ return SumWithoutSelectorMethods[type];
}
///
- /// Returns the for the method with a selector for the given type.
+ /// Returns the for the method with a selector for the given type.
///
/// The generic type of the method to create.
/// The .
- public static MethodInfo GetAverageWithSelector([NotNull] Type type)
+ public static MethodInfo GetSumWithSelector([NotNull] Type type)
{
Check.NotNull(type, nameof(type));
- return AverageWithSelectorMethods[type];
+ return SumWithSelectorMethods[type];
}
- private static Dictionary SumWithoutSelectorMethods { get; }
- private static Dictionary SumWithSelectorMethods { get; }
private static Dictionary AverageWithoutSelectorMethods { get; }
private static Dictionary AverageWithSelectorMethods { get; }
+ private static Dictionary SumWithoutSelectorMethods { get; }
+ private static Dictionary SumWithSelectorMethods { get; }
static QueryableMethods()
{
- var queryableMethods = typeof(Queryable)
- .GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly).ToList();
-
- AsQueryable = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.AsQueryable) && mi.IsGenericMethod && mi.GetParameters().Length == 1);
- Cast = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.Cast) && mi.GetParameters().Length == 1);
- OfType = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.OfType) && mi.GetParameters().Length == 1);
-
- All = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.All)
- && mi.GetParameters().Length == 2
- && IsExpressionOfFunc(mi.GetParameters()[1].ParameterType));
- AnyWithoutPredicate = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.Any) && mi.GetParameters().Length == 1);
- AnyWithPredicate = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.Any)
- && mi.GetParameters().Length == 2
- && IsExpressionOfFunc(mi.GetParameters()[1].ParameterType));
- Contains = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.Contains) && mi.GetParameters().Length == 2);
-
- Concat = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.Concat) && mi.GetParameters().Length == 2);
- Except = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.Except) && mi.GetParameters().Length == 2);
- Intersect = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.Intersect) && mi.GetParameters().Length == 2);
- Union = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.Union) && mi.GetParameters().Length == 2);
-
- CountWithoutPredicate = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.Count) && mi.GetParameters().Length == 1);
- CountWithPredicate = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.Count)
- && mi.GetParameters().Length == 2
- && IsExpressionOfFunc(mi.GetParameters()[1].ParameterType));
- LongCountWithoutPredicate = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.LongCount) && mi.GetParameters().Length == 1);
- LongCountWithPredicate = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.LongCount)
- && mi.GetParameters().Length == 2
- && IsExpressionOfFunc(mi.GetParameters()[1].ParameterType));
- MinWithSelector = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.Min)
- && mi.GetParameters().Length == 2
- && IsExpressionOfFunc(mi.GetParameters()[1].ParameterType));
- MinWithoutSelector = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.Min) && mi.GetParameters().Length == 1);
- MaxWithSelector = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.Max)
- && mi.GetParameters().Length == 2
- && IsExpressionOfFunc(mi.GetParameters()[1].ParameterType));
- MaxWithoutSelector = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.Max) && mi.GetParameters().Length == 1);
-
- ElementAt = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.ElementAt) && mi.GetParameters().Length == 2);
- ElementAtOrDefault = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.ElementAtOrDefault) && mi.GetParameters().Length == 2);
- FirstWithoutPredicate = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.First) && mi.GetParameters().Length == 1);
- FirstWithPredicate = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.First)
- && mi.GetParameters().Length == 2
- && IsExpressionOfFunc(mi.GetParameters()[1].ParameterType));
- FirstOrDefaultWithoutPredicate = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.FirstOrDefault) && mi.GetParameters().Length == 1);
- FirstOrDefaultWithPredicate = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.FirstOrDefault)
- && mi.GetParameters().Length == 2
- && IsExpressionOfFunc(mi.GetParameters()[1].ParameterType));
- SingleWithoutPredicate = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.Single) && mi.GetParameters().Length == 1);
- SingleWithPredicate = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.Single)
- && mi.GetParameters().Length == 2
- && IsExpressionOfFunc(mi.GetParameters()[1].ParameterType));
- SingleOrDefaultWithoutPredicate = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.SingleOrDefault) && mi.GetParameters().Length == 1);
- SingleOrDefaultWithPredicate = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.SingleOrDefault)
- && mi.GetParameters().Length == 2
- && IsExpressionOfFunc(mi.GetParameters()[1].ParameterType));
- LastWithoutPredicate = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.Last) && mi.GetParameters().Length == 1);
- LastWithPredicate = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.Last)
- && mi.GetParameters().Length == 2
- && IsExpressionOfFunc(mi.GetParameters()[1].ParameterType));
- LastOrDefaultWithoutPredicate = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.LastOrDefault) && mi.GetParameters().Length == 1);
- LastOrDefaultWithPredicate = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.LastOrDefault)
- && mi.GetParameters().Length == 2
- && IsExpressionOfFunc(mi.GetParameters()[1].ParameterType));
-
- Distinct = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.Distinct) && mi.GetParameters().Length == 1);
- Reverse = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.Reverse) && mi.GetParameters().Length == 1);
- Where = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.Where)
- && mi.GetParameters().Length == 2
- && IsExpressionOfFunc(mi.GetParameters()[1].ParameterType));
- Select = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.Select)
- && mi.GetParameters().Length == 2
- && IsExpressionOfFunc(mi.GetParameters()[1].ParameterType));
- Skip = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.Skip) && mi.GetParameters().Length == 2);
- Take = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.Take) && mi.GetParameters().Length == 2);
- SkipWhile = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.SkipWhile)
- && mi.GetParameters().Length == 2
- && IsExpressionOfFunc(mi.GetParameters()[1].ParameterType));
- TakeWhile = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.TakeWhile)
- && mi.GetParameters().Length == 2
- && IsExpressionOfFunc(mi.GetParameters()[1].ParameterType));
- OrderBy = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.OrderBy)
- && mi.GetParameters().Length == 2
- && IsExpressionOfFunc(mi.GetParameters()[1].ParameterType));
- OrderByDescending = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.OrderByDescending)
- && mi.GetParameters().Length == 2
- && IsExpressionOfFunc(mi.GetParameters()[1].ParameterType));
- ThenBy = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.ThenBy)
- && mi.GetParameters().Length == 2
- && IsExpressionOfFunc(mi.GetParameters()[1].ParameterType));
- ThenByDescending = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.ThenByDescending)
- && mi.GetParameters().Length == 2
- && IsExpressionOfFunc(mi.GetParameters()[1].ParameterType));
- DefaultIfEmptyWithoutArgument = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.DefaultIfEmpty) && mi.GetParameters().Length == 1);
- DefaultIfEmptyWithArgument = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.DefaultIfEmpty) && mi.GetParameters().Length == 2);
-
- Join = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.Join) && mi.GetParameters().Length == 5);
- GroupJoin = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.GroupJoin) && mi.GetParameters().Length == 5);
- SelectManyWithCollectionSelector = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.SelectMany)
- && mi.GetParameters().Length == 3
- && IsExpressionOfFunc(mi.GetParameters()[1].ParameterType));
- SelectManyWithoutCollectionSelector = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.SelectMany)
- && mi.GetParameters().Length == 2
- && IsExpressionOfFunc(mi.GetParameters()[1].ParameterType));
-
- GroupByWithKeySelector = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.GroupBy)
- && mi.GetParameters().Length == 2
- && IsExpressionOfFunc(mi.GetParameters()[1].ParameterType));
- GroupByWithKeyElementSelector = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.GroupBy)
- && mi.GetParameters().Length == 3
- && IsExpressionOfFunc(mi.GetParameters()[1].ParameterType)
- && IsExpressionOfFunc(mi.GetParameters()[2].ParameterType));
- GroupByWithKeyElementResultSelector = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.GroupBy)
- && mi.GetParameters().Length == 4
- && IsExpressionOfFunc(mi.GetParameters()[1].ParameterType)
- && IsExpressionOfFunc(mi.GetParameters()[2].ParameterType)
- && IsExpressionOfFunc(
- mi.GetParameters()[3].ParameterType, 3));
- GroupByWithKeyResultSelector = queryableMethods.Single(
- mi => mi.Name == nameof(Queryable.GroupBy)
- && mi.GetParameters().Length == 3
- && IsExpressionOfFunc(mi.GetParameters()[1].ParameterType)
- && IsExpressionOfFunc(
- mi.GetParameters()[2].ParameterType, 3));
-
- SumWithoutSelectorMethods = new Dictionary
+ var queryableMethodGroups = typeof(Queryable)
+ .GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly)
+ .GroupBy(mi => mi.Name)
+ .ToDictionary(e => e.Key, l => l.ToList());
+
+ All = GetMethod(nameof(Queryable.All), 1,
+ types => new[]
+ {
+ typeof(IQueryable<>).MakeGenericType(types[0]),
+ typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(types[0], typeof(bool)))
+ });
+
+ AnyWithoutPredicate = GetMethod(nameof(Queryable.Any), 1,
+ types => new[] { typeof(IQueryable<>).MakeGenericType(types[0]) });
+
+ AnyWithPredicate = GetMethod(nameof(Queryable.Any), 1,
+ types => new[]
+ {
+ typeof(IQueryable<>).MakeGenericType(types[0]),
+ typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(types[0], typeof(bool)))
+ });
+
+ AsQueryable = GetMethod(nameof(Queryable.AsQueryable), 1,
+ types => new[] { typeof(IEnumerable<>).MakeGenericType(types[0]) });
+
+ Cast = GetMethod(nameof(Queryable.Cast), 1, types => new[] { typeof(IQueryable) });
+
+ Concat = GetMethod(nameof(Queryable.Concat), 1,
+ types => new[]
+ {
+ typeof(IQueryable<>).MakeGenericType(types[0]),
+ typeof(IEnumerable<>).MakeGenericType(types[0])
+ });
+
+ Contains = GetMethod(nameof(Queryable.Contains), 1,
+ types => new[]
+ {
+ typeof(IQueryable<>).MakeGenericType(types[0]),
+ types[0]
+ });
+
+ CountWithoutPredicate = GetMethod(nameof(Queryable.Count), 1,
+ types => new[] { typeof(IQueryable<>).MakeGenericType(types[0]) });
+
+ CountWithPredicate = GetMethod(nameof(Queryable.Count), 1,
+ types => new[]
+ {
+ typeof(IQueryable<>).MakeGenericType(types[0]),
+ typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(types[0], typeof(bool)))
+ });
+
+ DefaultIfEmptyWithoutArgument = GetMethod(nameof(Queryable.DefaultIfEmpty), 1,
+ types => new[] { typeof(IQueryable<>).MakeGenericType(types[0]) });
+
+ DefaultIfEmptyWithArgument = GetMethod(nameof(Queryable.DefaultIfEmpty), 1,
+ types => new[]
+ {
+ typeof(IQueryable<>).MakeGenericType(types[0]),
+ types[0]
+ });
+
+ Distinct = GetMethod(nameof(Queryable.Distinct), 1, types => new[] { typeof(IQueryable<>).MakeGenericType(types[0]) });
+
+ ElementAt = GetMethod(nameof(Queryable.ElementAt), 1,
+ types => new[]
+ {
+ typeof(IQueryable<>).MakeGenericType(types[0]),
+ typeof(int)
+ });
+
+ ElementAtOrDefault = GetMethod(nameof(Queryable.ElementAtOrDefault), 1,
+ types => new[]
+ {
+ typeof(IQueryable<>).MakeGenericType(types[0]),
+ typeof(int)
+ });
+
+ Except = GetMethod(nameof(Queryable.Except), 1,
+ types => new[]
+ {
+ typeof(IQueryable<>).MakeGenericType(types[0]),
+ typeof(IEnumerable<>).MakeGenericType(types[0])
+ });
+
+ FirstWithoutPredicate = GetMethod(nameof(Queryable.First), 1, types => new[] { typeof(IQueryable<>).MakeGenericType(types[0]) });
+
+ FirstWithPredicate = GetMethod(nameof(Queryable.First), 1,
+ types => new[]
+ {
+ typeof(IQueryable<>).MakeGenericType(types[0]),
+ typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(types[0], typeof(bool)))
+ });
+
+ FirstOrDefaultWithoutPredicate = GetMethod(nameof(Queryable.FirstOrDefault), 1,
+ types => new[] { typeof(IQueryable<>).MakeGenericType(types[0]) });
+
+ FirstOrDefaultWithPredicate = GetMethod(nameof(Queryable.FirstOrDefault), 1,
+ types => new[]
+ {
+ typeof(IQueryable<>).MakeGenericType(types[0]),
+ typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(types[0], typeof(bool)))
+ });
+
+ GroupByWithKeySelector = GetMethod(nameof(Queryable.GroupBy), 2,
+ types => new[]
+ {
+ typeof(IQueryable<>).MakeGenericType(types[0]),
+ typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(types[0], types[1]))
+ });
+
+ GroupByWithKeyElementSelector = GetMethod(nameof(Queryable.GroupBy), 3,
+ types => new[]
+ {
+ typeof(IQueryable<>).MakeGenericType(types[0]),
+ typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(types[0], types[1])),
+ typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(types[0], types[2]))
+ });
+
+ GroupByWithKeyElementResultSelector = GetMethod(nameof(Queryable.GroupBy), 4,
+ types => new[]
+ {
+ typeof(IQueryable<>).MakeGenericType(types[0]),
+ typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(types[0], types[1])),
+ typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(types[0], types[2])),
+ typeof(Expression<>).MakeGenericType(typeof(Func<,,>).MakeGenericType(
+ types[1], typeof(IEnumerable<>).MakeGenericType(types[2]), types[3]))
+ });
+
+ GroupByWithKeyResultSelector = GetMethod(nameof(Queryable.GroupBy), 3,
+ types => new[]
+ {
+ typeof(IQueryable<>).MakeGenericType(types[0]),
+ typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(types[0], types[1])),
+ typeof(Expression<>).MakeGenericType(typeof(Func<,,>).MakeGenericType(
+ types[1], typeof(IEnumerable<>).MakeGenericType(types[0]), types[2]))
+ });
+
+ GroupJoin = GetMethod(nameof(Queryable.GroupJoin), 4,
+ types => new[]
+ {
+ typeof(IQueryable<>).MakeGenericType(types[0]),
+ typeof(IEnumerable<>).MakeGenericType(types[1]),
+ typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(types[0], types[2])),
+ typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(types[1], types[2])),
+ typeof(Expression<>).MakeGenericType(typeof(Func<,,>).MakeGenericType(
+ types[0], typeof(IEnumerable<>).MakeGenericType(types[1]), types[3]))
+ });
+
+ Intersect = GetMethod(nameof(Queryable.Intersect), 1,
+ types => new[]
+ {
+ typeof(IQueryable<>).MakeGenericType(types[0]),
+ typeof(IEnumerable<>).MakeGenericType(types[0])
+ });
+
+ Join = GetMethod(nameof(Queryable.Join), 4,
+ types => new[]
+ {
+ typeof(IQueryable<>).MakeGenericType(types[0]),
+ typeof(IEnumerable<>).MakeGenericType(types[1]),
+ typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(types[0], types[2])),
+ typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(types[1], types[2])),
+ typeof(Expression<>).MakeGenericType(typeof(Func<,,>).MakeGenericType(types[0], types[1], types[3]))
+ });
+
+ LastWithoutPredicate = GetMethod(nameof(Queryable.Last), 1, types => new[] { typeof(IQueryable<>).MakeGenericType(types[0]) });
+
+ LastWithPredicate = GetMethod(nameof(Queryable.Last), 1,
+ types => new[]
+ {
+ typeof(IQueryable<>).MakeGenericType(types[0]),
+ typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(types[0], typeof(bool)))
+ });
+
+ LastOrDefaultWithoutPredicate = GetMethod(nameof(Queryable.LastOrDefault), 1,
+ types => new[] { typeof(IQueryable<>).MakeGenericType(types[0]) });
+
+ LastOrDefaultWithPredicate = GetMethod(nameof(Queryable.LastOrDefault), 1,
+ types => new[]
+ {
+ typeof(IQueryable<>).MakeGenericType(types[0]),
+ typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(types[0], typeof(bool)))
+ });
+
+ LongCountWithoutPredicate = GetMethod(nameof(Queryable.LongCount), 1,
+ types => new[] { typeof(IQueryable<>).MakeGenericType(types[0]) });
+
+ LongCountWithPredicate = GetMethod(nameof(Queryable.LongCount), 1,
+ types => new[]
+ {
+ typeof(IQueryable<>).MakeGenericType(types[0]),
+ typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(types[0], typeof(bool)))
+ });
+
+ MaxWithoutSelector = GetMethod(nameof(Queryable.Max), 1, types => new[] { typeof(IQueryable<>).MakeGenericType(types[0]) });
+
+ MaxWithSelector = GetMethod(nameof(Queryable.Max), 2,
+ types => new[]
+ {
+ typeof(IQueryable<>).MakeGenericType(types[0]),
+ typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(types[0], types[1]))
+ });
+
+ MinWithoutSelector = GetMethod(nameof(Queryable.Min), 1, types => new[] { typeof(IQueryable<>).MakeGenericType(types[0]) });
+
+ MinWithSelector = GetMethod(nameof(Queryable.Min), 2,
+ types => new[]
+ {
+ typeof(IQueryable<>).MakeGenericType(types[0]),
+ typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(types[0], types[1]))
+ });
+
+ OfType = GetMethod(nameof(Queryable.OfType), 1, types => new[] { typeof(IQueryable) });
+
+ OrderBy = GetMethod(nameof(Queryable.OrderBy), 2,
+ types => new[]
+ {
+ typeof(IQueryable<>).MakeGenericType(types[0]),
+ typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(types[0], types[1]))
+ });
+
+ OrderByDescending = GetMethod(nameof(Queryable.OrderByDescending), 2,
+ types => new[]
+ {
+ typeof(IQueryable<>).MakeGenericType(types[0]),
+ typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(types[0], types[1]))
+ });
+
+ Reverse = GetMethod(nameof(Queryable.Reverse), 1, types => new[] { typeof(IQueryable<>).MakeGenericType(types[0]) });
+
+ Select = GetMethod(nameof(Queryable.Select), 2,
+ types => new[]
+ {
+ typeof(IQueryable<>).MakeGenericType(types[0]),
+ typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(types[0], types[1]))
+ });
+
+ SelectManyWithoutCollectionSelector = GetMethod(nameof(Queryable.SelectMany), 2,
+ types => new[]
+ {
+ typeof(IQueryable<>).MakeGenericType(types[0]),
+ typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(
+ types[0], typeof(IEnumerable<>).MakeGenericType(types[1])))
+ });
+
+ SelectManyWithCollectionSelector = GetMethod(nameof(Queryable.SelectMany), 3,
+ types => new[]
+ {
+ typeof(IQueryable<>).MakeGenericType(types[0]),
+ typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(
+ types[0], typeof(IEnumerable<>).MakeGenericType(types[1]))),
+ typeof(Expression<>).MakeGenericType(typeof(Func<,,>).MakeGenericType(types[0], types[1], types[2]))
+ });
+
+ SingleWithoutPredicate = GetMethod(nameof(Queryable.Single), 1, types => new[] { typeof(IQueryable<>).MakeGenericType(types[0]) });
+
+ SingleWithPredicate = GetMethod(nameof(Queryable.Single), 1,
+ types => new[]
+ {
+ typeof(IQueryable<>).MakeGenericType(types[0]),
+ typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(types[0], typeof(bool)))
+ });
+
+ SingleOrDefaultWithoutPredicate = GetMethod(nameof(Queryable.SingleOrDefault), 1,
+ types => new[] { typeof(IQueryable<>).MakeGenericType(types[0]) });
+
+ SingleOrDefaultWithPredicate = GetMethod(nameof(Queryable.SingleOrDefault), 1,
+ types => new[]
+ {
+ typeof(IQueryable<>).MakeGenericType(types[0]),
+ typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(types[0], typeof(bool)))
+ });
+
+ Skip = GetMethod(nameof(Queryable.Skip), 1,
+ types => new[]
+ {
+ typeof(IQueryable<>).MakeGenericType(types[0]),
+ typeof(int)
+ });
+
+ SkipWhile = GetMethod(nameof(Queryable.SkipWhile), 1,
+ types => new[]
+ {
+ typeof(IQueryable<>).MakeGenericType(types[0]),
+ typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(types[0], typeof(bool)))
+ });
+
+ Take = GetMethod(nameof(Queryable.Take), 1,
+ types => new[]
+ {
+ typeof(IQueryable<>).MakeGenericType(types[0]),
+ typeof(int)
+ });
+
+ TakeWhile = GetMethod(nameof(Queryable.TakeWhile), 1,
+ types => new[]
+ {
+ typeof(IQueryable<>).MakeGenericType(types[0]),
+ typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(types[0], typeof(bool)))
+ });
+
+ ThenBy = GetMethod(nameof(Queryable.ThenBy), 2,
+ types => new[]
+ {
+ typeof(IOrderedQueryable<>).MakeGenericType(types[0]),
+ typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(types[0], types[1]))
+ });
+
+ ThenByDescending = GetMethod(nameof(Queryable.ThenByDescending), 2,
+ types => new[]
+ {
+ typeof(IOrderedQueryable<>).MakeGenericType(types[0]),
+ typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(types[0], types[1]))
+ });
+
+ Union = GetMethod(nameof(Queryable.Union), 1,
+ types => new[]
+ {
+ typeof(IQueryable<>).MakeGenericType(types[0]),
+ typeof(IEnumerable<>).MakeGenericType(types[0])
+ });
+
+ Where = GetMethod(nameof(Queryable.Where), 1,
+ types => new[]
+ {
+ typeof(IQueryable<>).MakeGenericType(types[0]),
+ typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(types[0], typeof(bool)))
+ });
+
+ var numericTypes = new[]
{
- { typeof(decimal), GetSumOrAverageWithoutSelector(queryableMethods, nameof(Queryable.Sum)) },
- { typeof(long), GetSumOrAverageWithoutSelector(queryableMethods, nameof(Queryable.Sum)) },
- { typeof(int), GetSumOrAverageWithoutSelector(queryableMethods, nameof(Queryable.Sum)) },
- { typeof(double), GetSumOrAverageWithoutSelector(queryableMethods, nameof(Queryable.Sum)) },
- { typeof(float), GetSumOrAverageWithoutSelector(queryableMethods, nameof(Queryable.Sum)) },
- { typeof(decimal?), GetSumOrAverageWithoutSelector(queryableMethods, nameof(Queryable.Sum)) },
- { typeof(long?), GetSumOrAverageWithoutSelector(queryableMethods, nameof(Queryable.Sum)) },
- { typeof(int?), GetSumOrAverageWithoutSelector(queryableMethods, nameof(Queryable.Sum)) },
- { typeof(double?), GetSumOrAverageWithoutSelector(queryableMethods, nameof(Queryable.Sum)) },
- { typeof(float?), GetSumOrAverageWithoutSelector(queryableMethods, nameof(Queryable.Sum)) }
+ typeof(int),
+ typeof(int?),
+ typeof(long),
+ typeof(long?),
+ typeof(float),
+ typeof(float?),
+ typeof(double),
+ typeof(double?),
+ typeof(decimal),
+ typeof(decimal?)
};
- SumWithSelectorMethods = new Dictionary
- {
- { typeof(decimal), GetSumOrAverageWithSelector(queryableMethods, nameof(Queryable.Sum)) },
- { typeof(long), GetSumOrAverageWithSelector(queryableMethods, nameof(Queryable.Sum)) },
- { typeof(int), GetSumOrAverageWithSelector(queryableMethods, nameof(Queryable.Sum)) },
- { typeof(double), GetSumOrAverageWithSelector(queryableMethods, nameof(Queryable.Sum)) },
- { typeof(float), GetSumOrAverageWithSelector(queryableMethods, nameof(Queryable.Sum)) },
- { typeof(decimal?), GetSumOrAverageWithSelector(queryableMethods, nameof(Queryable.Sum)) },
- { typeof(long?), GetSumOrAverageWithSelector(queryableMethods, nameof(Queryable.Sum)) },
- { typeof(int?), GetSumOrAverageWithSelector(queryableMethods, nameof(Queryable.Sum)) },
- { typeof(double?), GetSumOrAverageWithSelector(queryableMethods, nameof(Queryable.Sum)) },
- { typeof(float?), GetSumOrAverageWithSelector(queryableMethods, nameof(Queryable.Sum)) }
- };
+ AverageWithoutSelectorMethods = new Dictionary();
+ AverageWithSelectorMethods = new Dictionary();
+ SumWithoutSelectorMethods = new Dictionary();
+ SumWithSelectorMethods = new Dictionary();
- AverageWithoutSelectorMethods = new Dictionary
+ foreach (var type in numericTypes)
{
- { typeof(decimal), GetSumOrAverageWithoutSelector(queryableMethods, nameof(Queryable.Average)) },
- { typeof(long), GetSumOrAverageWithoutSelector(queryableMethods, nameof(Queryable.Average)) },
- { typeof(int), GetSumOrAverageWithoutSelector(queryableMethods, nameof(Queryable.Average)) },
- { typeof(double), GetSumOrAverageWithoutSelector(queryableMethods, nameof(Queryable.Average)) },
- { typeof(float), GetSumOrAverageWithoutSelector(queryableMethods, nameof(Queryable.Average)) },
- { typeof(decimal?), GetSumOrAverageWithoutSelector(queryableMethods, nameof(Queryable.Average)) },
- { typeof(long?), GetSumOrAverageWithoutSelector(queryableMethods, nameof(Queryable.Average)) },
- { typeof(int?), GetSumOrAverageWithoutSelector(queryableMethods, nameof(Queryable.Average)) },
- { typeof(double?), GetSumOrAverageWithoutSelector(queryableMethods, nameof(Queryable.Average)) },
- { typeof(float?), GetSumOrAverageWithoutSelector(queryableMethods, nameof(Queryable.Average)) }
- };
-
- AverageWithSelectorMethods = new Dictionary
- {
- { typeof(decimal), GetSumOrAverageWithSelector(queryableMethods, nameof(Queryable.Average)) },
- { typeof(long), GetSumOrAverageWithSelector(queryableMethods, nameof(Queryable.Average)) },
- { typeof(int), GetSumOrAverageWithSelector(queryableMethods, nameof(Queryable.Average)) },
- { typeof(double), GetSumOrAverageWithSelector(queryableMethods, nameof(Queryable.Average)) },
- { typeof(float), GetSumOrAverageWithSelector(queryableMethods, nameof(Queryable.Average)) },
- { typeof(decimal?), GetSumOrAverageWithSelector(queryableMethods, nameof(Queryable.Average)) },
- { typeof(long?), GetSumOrAverageWithSelector(queryableMethods, nameof(Queryable.Average)) },
- { typeof(int?), GetSumOrAverageWithSelector(queryableMethods, nameof(Queryable.Average)) },
- { typeof(double?), GetSumOrAverageWithSelector(queryableMethods, nameof(Queryable.Average)) },
- { typeof(float?), GetSumOrAverageWithSelector(queryableMethods, nameof(Queryable.Average)) }
- };
-
- static MethodInfo GetSumOrAverageWithoutSelector(List queryableMethods, string methodName)
- => queryableMethods.Single(
- mi => mi.Name == methodName
- && mi.GetParameters().Length == 1
- && mi.GetParameters()[0].ParameterType.GetGenericArguments()[0] == typeof(T));
-
- static MethodInfo GetSumOrAverageWithSelector(List queryableMethods, string methodName)
- => queryableMethods.Single(
- mi => mi.Name == methodName
- && mi.GetParameters().Length == 2
- && IsSelector(mi.GetParameters()[1].ParameterType));
-
- static bool IsExpressionOfFunc(Type type, int funcGenericArgs = 2)
- => type.IsGenericType
- && type.GetGenericTypeDefinition() == typeof(Expression<>)
- && type.GetGenericArguments()[0].IsGenericType
- && type.GetGenericArguments()[0].GetGenericArguments().Length == funcGenericArgs;
-
- static bool IsSelector(Type type)
- => type.IsGenericType
- && type.GetGenericTypeDefinition() == typeof(Expression<>)
- && type.GetGenericArguments()[0].IsGenericType
- && type.GetGenericArguments()[0].GetGenericArguments().Length == 2
- && type.GetGenericArguments()[0].GetGenericArguments()[1] == typeof(T);
+ AverageWithoutSelectorMethods[type] = GetMethod(
+ nameof(Queryable.Average), 0, types => new[] { typeof(IQueryable<>).MakeGenericType(type) });
+ AverageWithSelectorMethods[type] = GetMethod(
+ nameof(Queryable.Average), 1, types => new[] {
+ typeof(IQueryable<>).MakeGenericType(types[0]),
+ typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(types[0], type))
+ });
+ SumWithoutSelectorMethods[type] = GetMethod(
+ nameof(Queryable.Sum), 0, types => new[] { typeof(IQueryable<>).MakeGenericType(type) });
+ SumWithSelectorMethods[type] = GetMethod(
+ nameof(Queryable.Sum), 1, types => new[] {
+ typeof(IQueryable<>).MakeGenericType(types[0]),
+ typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(types[0], type))
+ });
+ }
+
+ MethodInfo GetMethod(string name, int genericParameterCount, Func parameterGenerator)
+ => queryableMethodGroups[name].Single(
+ mi => ((genericParameterCount == 0 && !mi.IsGenericMethod)
+ || (mi.IsGenericMethod && mi.GetGenericArguments().Length == genericParameterCount))
+ && mi.GetParameters().Select(e => e.ParameterType).SequenceEqual(
+ parameterGenerator(mi.IsGenericMethod ? mi.GetGenericArguments() : Array.Empty())));
}
}
-}
+}
\ No newline at end of file
diff --git a/src/Shared/EnumerableMethods.cs b/src/Shared/EnumerableMethods.cs
index 3fe8c76250f..06e316dbe52 100644
--- a/src/Shared/EnumerableMethods.cs
+++ b/src/Shared/EnumerableMethods.cs
@@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
+using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
@@ -10,73 +11,196 @@ namespace Microsoft.EntityFrameworkCore
{
internal static class EnumerableMethods
{
- public static MethodInfo AsEnumerable { get; }
- public static MethodInfo Cast { get; }
- public static MethodInfo OfType { get; }
+ //public static MethodInfo AggregateWithoutSeed { get; }
+
+ //public static MethodInfo AggregateWithSeedWithoutSelector { get; }
+
+ //public static MethodInfo AggregateWithSeedSelector { get; }
public static MethodInfo All { get; }
+
public static MethodInfo AnyWithoutPredicate { get; }
+
public static MethodInfo AnyWithPredicate { get; }
- public static MethodInfo Contains { get; }
- public static MethodInfo SequenceEqual { get; }
- public static MethodInfo ToList { get; }
- public static MethodInfo ToArray { get; }
+ //public static Append { get; }
+
+ public static MethodInfo AsEnumerable { get; }
+
+ public static MethodInfo Cast { get; }
public static MethodInfo Concat { get; }
- public static MethodInfo Except { get; }
- public static MethodInfo Intersect { get; }
- public static MethodInfo Union { get; }
+
+ public static MethodInfo Contains { get; }
+
+ //public static MethodInfo ContainsWithComparer { get; }
public static MethodInfo CountWithoutPredicate { get; }
+
public static MethodInfo CountWithPredicate { get; }
- public static MethodInfo LongCountWithoutPredicate { get; }
- public static MethodInfo LongCountWithPredicate { get; }
- public static MethodInfo MinWithSelector { get; }
- public static MethodInfo MinWithoutSelector { get; }
- public static MethodInfo MaxWithSelector { get; }
- public static MethodInfo MaxWithoutSelector { get; }
+
+ public static MethodInfo DefaultIfEmptyWithoutArgument { get; }
+
+ public static MethodInfo DefaultIfEmptyWithArgument { get; }
+
+ public static MethodInfo Distinct { get; }
+
+ //public static MethodInfo DistinctWithComparer { get; }
public static MethodInfo ElementAt { get; }
+
public static MethodInfo ElementAtOrDefault { get; }
+
+ //public static MethodInfo Empty { get; }
+
+ public static MethodInfo Except { get; }
+
+ //public static MethodInfo ExceptWithComparer { get; }
+
public static MethodInfo FirstWithoutPredicate { get; }
+
public static MethodInfo FirstWithPredicate { get; }
+
public static MethodInfo FirstOrDefaultWithoutPredicate { get; }
+
public static MethodInfo FirstOrDefaultWithPredicate { get; }
- public static MethodInfo SingleWithoutPredicate { get; }
- public static MethodInfo SingleWithPredicate { get; }
- public static MethodInfo SingleOrDefaultWithoutPredicate { get; }
- public static MethodInfo SingleOrDefaultWithPredicate { get; }
+
+ public static MethodInfo GroupByWithKeySelector { get; }
+
+ public static MethodInfo GroupByWithKeyElementSelector { get; }
+
+ //public static MethodInfo GroupByWithKeySelectorAndComparer { get; }
+
+ //public static MethodInfo GroupByWithKeyElementSelectorAndComparer { get; }
+
+ public static MethodInfo GroupByWithKeyElementResultSelector { get; }
+
+ public static MethodInfo GroupByWithKeyResultSelector { get; }
+
+ //public static MethodInfo GroupByWithKeyResultSelectorAndComparer { get; }
+
+ //public static MethodInfo GroupByWithKeyElementResultSelectorAndComparer { get; }
+
+ public static MethodInfo GroupJoin { get; }
+
+ //public static MethodInfo GroupJoinWithComparer { get; }
+
+ public static MethodInfo Intersect { get; }
+
+ //public static MethodInfo IntersectWithComparer { get; }
+
+ public static MethodInfo Join { get; }
+
+ //public static MethodInfo JoinWithComparer { get; }
+
public static MethodInfo LastWithoutPredicate { get; }
+
public static MethodInfo LastWithPredicate { get; }
+
public static MethodInfo LastOrDefaultWithoutPredicate { get; }
+
public static MethodInfo LastOrDefaultWithPredicate { get; }
- public static MethodInfo Distinct { get; }
+ public static MethodInfo LongCountWithoutPredicate { get; }
+
+ public static MethodInfo LongCountWithPredicate { get; }
+
+ public static MethodInfo MaxWithoutSelector { get; }
+
+ public static MethodInfo MaxWithSelector { get; }
+
+ public static MethodInfo MinWithoutSelector { get; }
+
+ public static MethodInfo MinWithSelector { get; }
+
+ public static MethodInfo OfType { get; }
+
+ public static MethodInfo OrderBy { get; }
+
+ //public static MethodInfo OrderByWithComparer { get; }
+
+ public static MethodInfo OrderByDescending { get; }
+
+ //public static MethodInfo OrderByDescendingWithComparer { get; }
+
+ //public static MethodInfo Prepend { get; }
+
+ //public static MethodInfo Range { get; }
+
+ //public static MethodInfo Repeat { get; }
+
public static MethodInfo Reverse { get; }
- public static MethodInfo Where { get; }
+
public static MethodInfo Select { get; }
+
public static MethodInfo SelectWithOrdinal { get; }
+
+ public static MethodInfo SelectManyWithoutCollectionSelector { get; }
+
+ //public static MethodInfo SelectManyWithoutCollectionSelectorOrdinal { get; }
+
+ public static MethodInfo SelectManyWithCollectionSelector { get; }
+
+ //public static MethodInfo SelectManyWithCollectionSelectorOrdinal { get; }
+
+ public static MethodInfo SequenceEqual { get; }
+
+ //public static MethodInfo SequenceEqualWithComparer { get; }
+
+ public static MethodInfo SingleWithoutPredicate { get; }
+
+ public static MethodInfo SingleWithPredicate { get; }
+
+ public static MethodInfo SingleOrDefaultWithoutPredicate { get; }
+
+ public static MethodInfo SingleOrDefaultWithPredicate { get; }
+
public static MethodInfo Skip { get; }
- public static MethodInfo Take { get; }
+
public static MethodInfo SkipWhile { get; }
+
+ //public static MethodInfo SkipWhileOrdinal { get; }
+
+ public static MethodInfo Take { get; }
+
public static MethodInfo TakeWhile { get; }
- public static MethodInfo OrderBy { get; }
- public static MethodInfo OrderByDescending { get; }
+
+ //public static MethodInfo TakeWhileOrdinal { get; }
+
public static MethodInfo ThenBy { get; }
+
+ //public static MethodInfo ThenByWithComparer { get; }
+
public static MethodInfo ThenByDescending { get; }
- public static MethodInfo DefaultIfEmptyWithoutArgument { get; }
- public static MethodInfo DefaultIfEmptyWithArgument { get; }
- public static MethodInfo Join { get; }
- public static MethodInfo GroupJoin { get; }
- public static MethodInfo SelectManyWithCollectionSelector { get; }
- public static MethodInfo SelectManyWithoutCollectionSelector { get; }
+ //public static MethodInfo ThenByDescendingWithComparer { get; }
- public static MethodInfo GroupByWithKeySelector { get; }
- public static MethodInfo GroupByWithKeyElementSelector { get; }
- public static MethodInfo GroupByWithKeyElementResultSelector { get; }
- public static MethodInfo GroupByWithKeyResultSelector { get; }
+ public static MethodInfo ToArray { get; }
+
+ //public static MethodInfo ToDictionaryWithKeySelector { get; }
+ //public static MethodInfo ToDictionaryWithKeySelectorAndComparer { get; }
+ //public static MethodInfo ToDictionaryWithKeyElementSelector { get; }
+ //public static MethodInfo ToDictionaryWithKeyElementSelectorAndComparer { get; }
+
+ //public static MethodInfo ToHashSet { get; }
+ //public static MethodInfo ToHashSetWithComparer { get; }
+
+ public static MethodInfo ToList { get; }
+
+ //public static MethodInfo ToLookupWithKeySelector { get; }
+ //public static MethodInfo ToLookupWithKeySelectorAndComparer { get; }
+ //public static MethodInfo ToLookupWithKeyElementSelector { get; }
+ //public static MethodInfo ToLookupWithKeyElementSelectorAndComparer { get; }
+
+ public static MethodInfo Union { get; }
+
+ //public static MethodInfo UnionWithComparer { get; }
+
+ public static MethodInfo Where { get; }
+
+ //public static MethodInfo WhereOrdinal { get; }
+
+ //public static MethodInfo Zip { get; }
private static Dictionary SumWithoutSelectorMethods { get; }
private static Dictionary SumWithSelectorMethods { get; }
@@ -135,337 +259,414 @@ public static MethodInfo GetMinWithSelector(Type type)
static EnumerableMethods()
{
- var enumerableMethods = typeof(Enumerable)
+ var queryableMethodGroups = typeof(Enumerable)
.GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly)
- .ToList();
-
- AsEnumerable = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.AsEnumerable) && mi.IsGenericMethod && mi.GetParameters().Length == 1);
- Cast = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.Cast) && mi.GetParameters().Length == 1);
- OfType = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.OfType) && mi.GetParameters().Length == 1);
-
- All = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.All)
- && mi.GetParameters().Length == 2
- && IsFunc(mi.GetParameters()[1].ParameterType));
- AnyWithoutPredicate = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.Any) && mi.GetParameters().Length == 1);
- AnyWithPredicate = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.Any)
- && mi.GetParameters().Length == 2
- && IsFunc(mi.GetParameters()[1].ParameterType));
- Contains = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.Contains) && mi.GetParameters().Length == 2);
- SequenceEqual = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.SequenceEqual) && mi.GetParameters().Length == 2);
-
- ToList = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.ToList) && mi.GetParameters().Length == 1);
- ToArray = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.ToArray) && mi.GetParameters().Length == 1);
-
- Concat = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.Concat) && mi.GetParameters().Length == 2);
- Except = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.Except) && mi.GetParameters().Length == 2);
- Intersect = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.Intersect) && mi.GetParameters().Length == 2);
- Union = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.Union) && mi.GetParameters().Length == 2);
-
- CountWithoutPredicate = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.Count) && mi.GetParameters().Length == 1);
- CountWithPredicate = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.Count)
- && mi.GetParameters().Length == 2
- && IsFunc(mi.GetParameters()[1].ParameterType));
- LongCountWithoutPredicate = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.LongCount) && mi.GetParameters().Length == 1);
- LongCountWithPredicate = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.LongCount)
- && mi.GetParameters().Length == 2
- && IsFunc(mi.GetParameters()[1].ParameterType));
- MinWithSelector = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.Min)
- && mi.GetParameters().Length == 2
- && mi.GetGenericArguments().Length == 2
- && IsFunc(mi.GetParameters()[1].ParameterType));
- MinWithoutSelector = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.Min)
- && mi.GetParameters().Length == 1
- && mi.IsGenericMethodDefinition);
- MaxWithSelector = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.Max)
- && mi.GetParameters().Length == 2
- && mi.GetGenericArguments().Length == 2
- && IsFunc(mi.GetParameters()[1].ParameterType));
- MaxWithoutSelector = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.Max)
- && mi.GetParameters().Length == 1
- && mi.IsGenericMethodDefinition);
-
- ElementAt = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.ElementAt) && mi.GetParameters().Length == 2);
- ElementAtOrDefault = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.ElementAtOrDefault) && mi.GetParameters().Length == 2);
- FirstWithoutPredicate = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.First) && mi.GetParameters().Length == 1);
- FirstWithPredicate = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.First)
- && mi.GetParameters().Length == 2
- && IsFunc(mi.GetParameters()[1].ParameterType));
- FirstOrDefaultWithoutPredicate = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.FirstOrDefault) && mi.GetParameters().Length == 1);
- FirstOrDefaultWithPredicate = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.FirstOrDefault)
- && mi.GetParameters().Length == 2
- && IsFunc(mi.GetParameters()[1].ParameterType));
- SingleWithoutPredicate = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.Single) && mi.GetParameters().Length == 1);
- SingleWithPredicate = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.Single)
- && mi.GetParameters().Length == 2
- && IsFunc(mi.GetParameters()[1].ParameterType));
- SingleOrDefaultWithoutPredicate = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.SingleOrDefault) && mi.GetParameters().Length == 1);
- SingleOrDefaultWithPredicate = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.SingleOrDefault)
- && mi.GetParameters().Length == 2
- && IsFunc(mi.GetParameters()[1].ParameterType));
- LastWithoutPredicate = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.Last) && mi.GetParameters().Length == 1);
- LastWithPredicate = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.Last)
- && mi.GetParameters().Length == 2
- && IsFunc(mi.GetParameters()[1].ParameterType));
- LastOrDefaultWithoutPredicate = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.LastOrDefault) && mi.GetParameters().Length == 1);
- LastOrDefaultWithPredicate = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.LastOrDefault)
- && mi.GetParameters().Length == 2
- && IsFunc(mi.GetParameters()[1].ParameterType));
-
- Distinct = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.Distinct) && mi.GetParameters().Length == 1);
- Reverse = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.Reverse) && mi.GetParameters().Length == 1);
- Where = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.Where)
- && mi.GetParameters().Length == 2
- && IsFunc(mi.GetParameters()[1].ParameterType));
- Select = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.Select)
- && mi.GetParameters().Length == 2
- && IsFunc(mi.GetParameters()[1].ParameterType));
- SelectWithOrdinal = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.Select)
- && mi.GetParameters().Length == 2
- && IsFunc(mi.GetParameters()[1].ParameterType, funcGenericArgs: 3));
- Skip = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.Skip) && mi.GetParameters().Length == 2);
- Take = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.Take) && mi.GetParameters().Length == 2);
- SkipWhile = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.SkipWhile)
- && mi.GetParameters().Length == 2
- && IsFunc(mi.GetParameters()[1].ParameterType));
- TakeWhile = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.TakeWhile)
- && mi.GetParameters().Length == 2
- && IsFunc(mi.GetParameters()[1].ParameterType));
- OrderBy = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.OrderBy)
- && mi.GetParameters().Length == 2
- && IsFunc(mi.GetParameters()[1].ParameterType));
- OrderByDescending = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.OrderByDescending)
- && mi.GetParameters().Length == 2
- && IsFunc(mi.GetParameters()[1].ParameterType));
- ThenBy = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.ThenBy)
- && mi.GetParameters().Length == 2
- && IsFunc(mi.GetParameters()[1].ParameterType));
- ThenByDescending = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.ThenByDescending)
- && mi.GetParameters().Length == 2
- && IsFunc(mi.GetParameters()[1].ParameterType));
- DefaultIfEmptyWithoutArgument = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.DefaultIfEmpty) && mi.GetParameters().Length == 1);
- DefaultIfEmptyWithArgument = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.DefaultIfEmpty) && mi.GetParameters().Length == 2);
-
- Join = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.Join) && mi.GetParameters().Length == 5);
- GroupJoin = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.GroupJoin) && mi.GetParameters().Length == 5);
- SelectManyWithCollectionSelector = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.SelectMany)
- && mi.GetParameters().Length == 3
- && IsFunc(mi.GetParameters()[1].ParameterType));
- SelectManyWithoutCollectionSelector = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.SelectMany)
- && mi.GetParameters().Length == 2
- && IsFunc(mi.GetParameters()[1].ParameterType));
-
- GroupByWithKeySelector = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.GroupBy)
- && mi.GetParameters().Length == 2
- && IsFunc(mi.GetParameters()[1].ParameterType));
- GroupByWithKeyElementSelector = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.GroupBy)
- && mi.GetParameters().Length == 3
- && IsFunc(mi.GetParameters()[1].ParameterType)
- && IsFunc(mi.GetParameters()[2].ParameterType));
- GroupByWithKeyElementResultSelector = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.GroupBy)
- && mi.GetParameters().Length == 4
- && IsFunc(mi.GetParameters()[1].ParameterType)
- && IsFunc(mi.GetParameters()[2].ParameterType)
- && IsFunc(
- mi.GetParameters()[3].ParameterType, 3));
- GroupByWithKeyResultSelector = enumerableMethods.Single(
- mi => mi.Name == nameof(Enumerable.GroupBy)
- && mi.GetParameters().Length == 3
- && IsFunc(mi.GetParameters()[1].ParameterType)
- && IsFunc(
- mi.GetParameters()[2].ParameterType, 3));
-
- SumWithoutSelectorMethods = new Dictionary
+ .GroupBy(mi => mi.Name)
+ .ToDictionary(e => e.Key, l => l.ToList());
+
+ All = GetMethod(nameof(Enumerable.All), 1,
+ types => new[]
+ {
+ typeof(IEnumerable<>).MakeGenericType(types[0]),
+ typeof(Func<,>).MakeGenericType(types[0], typeof(bool))
+ });
+
+ AnyWithoutPredicate = GetMethod(nameof(Enumerable.Any), 1,
+ types => new[] { typeof(IEnumerable<>).MakeGenericType(types[0]) });
+
+ AnyWithPredicate = GetMethod(nameof(Enumerable.Any), 1,
+ types => new[]
+ {
+ typeof(IEnumerable<>).MakeGenericType(types[0]),
+ typeof(Func<,>).MakeGenericType(types[0], typeof(bool))
+ });
+
+ AsEnumerable = GetMethod(nameof(Enumerable.AsEnumerable), 1,
+ types => new[] { typeof(IEnumerable<>).MakeGenericType(types[0]) });
+
+ Cast = GetMethod(nameof(Enumerable.Cast), 1, types => new[] { typeof(IEnumerable) });
+
+ Concat = GetMethod(nameof(Enumerable.Concat), 1,
+ types => new[]
+ {
+ typeof(IEnumerable<>).MakeGenericType(types[0]),
+ typeof(IEnumerable<>).MakeGenericType(types[0])
+ });
+
+ Contains = GetMethod(nameof(Enumerable.Contains), 1,
+ types => new[]
+ {
+ typeof(IEnumerable<>).MakeGenericType(types[0]),
+ types[0]
+ });
+
+ CountWithoutPredicate = GetMethod(nameof(Enumerable.Count), 1,
+ types => new[] { typeof(IEnumerable<>).MakeGenericType(types[0]) });
+
+ CountWithPredicate = GetMethod(nameof(Enumerable.Count), 1,
+ types => new[]
+ {
+ typeof(IEnumerable<>).MakeGenericType(types[0]),
+ typeof(Func<,>).MakeGenericType(types[0], typeof(bool))
+ });
+
+ DefaultIfEmptyWithoutArgument = GetMethod(nameof(Enumerable.DefaultIfEmpty), 1,
+ types => new[] { typeof(IEnumerable<>).MakeGenericType(types[0]) });
+
+ DefaultIfEmptyWithArgument = GetMethod(nameof(Enumerable.DefaultIfEmpty), 1,
+ types => new[]
+ {
+ typeof(IEnumerable<>).MakeGenericType(types[0]),
+ types[0]
+ });
+
+ Distinct = GetMethod(nameof(Enumerable.Distinct), 1, types => new[] { typeof(IEnumerable<>).MakeGenericType(types[0]) });
+
+ ElementAt = GetMethod(nameof(Enumerable.ElementAt), 1,
+ types => new[]
+ {
+ typeof(IEnumerable<>).MakeGenericType(types[0]),
+ typeof(int)
+ });
+
+ ElementAtOrDefault = GetMethod(nameof(Enumerable.ElementAtOrDefault), 1,
+ types => new[]
+ {
+ typeof(IEnumerable<>).MakeGenericType(types[0]),
+ typeof(int)
+ });
+
+ Except = GetMethod(nameof(Enumerable.Except), 1,
+ types => new[]
+ {
+ typeof(IEnumerable<>).MakeGenericType(types[0]),
+ typeof(IEnumerable<>).MakeGenericType(types[0])
+ });
+
+ FirstWithoutPredicate = GetMethod(nameof(Enumerable.First), 1, types => new[] { typeof(IEnumerable<>).MakeGenericType(types[0]) });
+
+ FirstWithPredicate = GetMethod(nameof(Enumerable.First), 1,
+ types => new[]
+ {
+ typeof(IEnumerable<>).MakeGenericType(types[0]),
+ typeof(Func<,>).MakeGenericType(types[0], typeof(bool))
+ });
+
+ FirstOrDefaultWithoutPredicate = GetMethod(nameof(Enumerable.FirstOrDefault), 1,
+ types => new[] { typeof(IEnumerable<>).MakeGenericType(types[0]) });
+
+ FirstOrDefaultWithPredicate = GetMethod(nameof(Enumerable.FirstOrDefault), 1,
+ types => new[]
+ {
+ typeof(IEnumerable<>).MakeGenericType(types[0]),
+ typeof(Func<,>).MakeGenericType(types[0], typeof(bool))
+ });
+
+ GroupByWithKeySelector = GetMethod(nameof(Enumerable.GroupBy), 2,
+ types => new[]
+ {
+ typeof(IEnumerable<>).MakeGenericType(types[0]),
+ typeof(Func<,>).MakeGenericType(types[0], types[1])
+ });
+
+ GroupByWithKeyElementSelector = GetMethod(nameof(Enumerable.GroupBy), 3,
+ types => new[]
+ {
+ typeof(IEnumerable<>).MakeGenericType(types[0]),
+ typeof(Func<,>).MakeGenericType(types[0], types[1]),
+ typeof(Func<,>).MakeGenericType(types[0], types[2])
+ });
+
+ GroupByWithKeyElementResultSelector = GetMethod(nameof(Enumerable.GroupBy), 4,
+ types => new[]
+ {
+ typeof(IEnumerable<>).MakeGenericType(types[0]),
+ typeof(Func<,>).MakeGenericType(types[0], types[1]),
+ typeof(Func<,>).MakeGenericType(types[0], types[2]),
+ typeof(Func<,,>).MakeGenericType(
+ types[1], typeof(IEnumerable<>).MakeGenericType(types[2]), types[3])
+ });
+
+ GroupByWithKeyResultSelector = GetMethod(nameof(Enumerable.GroupBy), 3,
+ types => new[]
+ {
+ typeof(IEnumerable<>).MakeGenericType(types[0]),
+ typeof(Func<,>).MakeGenericType(types[0], types[1]),
+ typeof(Func<,,>).MakeGenericType(
+ types[1], typeof(IEnumerable<>).MakeGenericType(types[0]), types[2])
+ });
+
+ GroupJoin = GetMethod(nameof(Enumerable.GroupJoin), 4,
+ types => new[]
+ {
+ typeof(IEnumerable<>).MakeGenericType(types[0]),
+ typeof(IEnumerable<>).MakeGenericType(types[1]),
+ typeof(Func<,>).MakeGenericType(types[0], types[2]),
+ typeof(Func<,>).MakeGenericType(types[1], types[2]),
+ typeof(Func<,,>).MakeGenericType(
+ types[0], typeof(IEnumerable<>).MakeGenericType(types[1]), types[3])
+ });
+
+ Intersect = GetMethod(nameof(Enumerable.Intersect), 1,
+ types => new[]
+ {
+ typeof(IEnumerable<>).MakeGenericType(types[0]),
+ typeof(IEnumerable<>).MakeGenericType(types[0])
+ });
+
+ Join = GetMethod(nameof(Enumerable.Join), 4,
+ types => new[]
+ {
+ typeof(IEnumerable<>).MakeGenericType(types[0]),
+ typeof(IEnumerable<>).MakeGenericType(types[1]),
+ typeof(Func<,>).MakeGenericType(types[0], types[2]),
+ typeof(Func<,>).MakeGenericType(types[1], types[2]),
+ typeof(Func<,,>).MakeGenericType(types[0], types[1], types[3])
+ });
+
+ LastWithoutPredicate = GetMethod(nameof(Enumerable.Last), 1, types => new[] { typeof(IEnumerable<>).MakeGenericType(types[0]) });
+
+ LastWithPredicate = GetMethod(nameof(Enumerable.Last), 1,
+ types => new[]
+ {
+ typeof(IEnumerable<>).MakeGenericType(types[0]),
+ typeof(Func<,>).MakeGenericType(types[0], typeof(bool))
+ });
+
+ LastOrDefaultWithoutPredicate = GetMethod(nameof(Enumerable.LastOrDefault), 1,
+ types => new[] { typeof(IEnumerable<>).MakeGenericType(types[0]) });
+
+ LastOrDefaultWithPredicate = GetMethod(nameof(Enumerable.LastOrDefault), 1,
+ types => new[]
+ {
+ typeof(IEnumerable<>).MakeGenericType(types[0]),
+ typeof(Func<,>).MakeGenericType(types[0], typeof(bool))
+ });
+
+ LongCountWithoutPredicate = GetMethod(nameof(Enumerable.LongCount), 1,
+ types => new[] { typeof(IEnumerable<>).MakeGenericType(types[0]) });
+
+ LongCountWithPredicate = GetMethod(nameof(Enumerable.LongCount), 1,
+ types => new[]
+ {
+ typeof(IEnumerable<>).MakeGenericType(types[0]),
+ typeof(Func<,>).MakeGenericType(types[0], typeof(bool))
+ });
+
+ MaxWithoutSelector = GetMethod(nameof(Enumerable.Max), 1, types => new[] { typeof(IEnumerable<>).MakeGenericType(types[0]) });
+
+ MaxWithSelector = GetMethod(nameof(Enumerable.Max), 2,
+ types => new[]
+ {
+ typeof(IEnumerable<>).MakeGenericType(types[0]),
+ typeof(Func<,>).MakeGenericType(types[0], types[1])
+ });
+
+ MinWithoutSelector = GetMethod(nameof(Enumerable.Min), 1, types => new[] { typeof(IEnumerable<>).MakeGenericType(types[0]) });
+
+ MinWithSelector = GetMethod(nameof(Enumerable.Min), 2,
+ types => new[]
+ {
+ typeof(IEnumerable<>).MakeGenericType(types[0]),
+ typeof(Func<,>).MakeGenericType(types[0], types[1])
+ });
+
+ OfType = GetMethod(nameof(Enumerable.OfType), 1, types => new[] { typeof(IEnumerable) });
+
+ OrderBy = GetMethod(nameof(Enumerable.OrderBy), 2,
+ types => new[]
+ {
+ typeof(IEnumerable<>).MakeGenericType(types[0]),
+ typeof(Func<,>).MakeGenericType(types[0], types[1])
+ });
+
+ OrderByDescending = GetMethod(nameof(Enumerable.OrderByDescending), 2,
+ types => new[]
+ {
+ typeof(IEnumerable<>).MakeGenericType(types[0]),
+ typeof(Func<,>).MakeGenericType(types[0], types[1])
+ });
+
+ Reverse = GetMethod(nameof(Enumerable.Reverse), 1, types => new[] { typeof(IEnumerable<>).MakeGenericType(types[0]) });
+
+ Select = GetMethod(nameof(Enumerable.Select), 2,
+ types => new[]
+ {
+ typeof(IEnumerable<>).MakeGenericType(types[0]),
+ typeof(Func<,>).MakeGenericType(types[0], types[1])
+ });
+
+ SelectWithOrdinal = GetMethod(nameof(Enumerable.Select), 2,
+ types => new[]
+ {
+ typeof(IEnumerable<>).MakeGenericType(types[0]),
+ typeof(Func<,,>).MakeGenericType(types[0], typeof(int), types[1])
+ });
+
+ SelectManyWithoutCollectionSelector = GetMethod(nameof(Enumerable.SelectMany), 2,
+ types => new[]
+ {
+ typeof(IEnumerable<>).MakeGenericType(types[0]),
+ typeof(Func<,>).MakeGenericType(
+ types[0], typeof(IEnumerable<>).MakeGenericType(types[1]))
+ });
+
+ SelectManyWithCollectionSelector = GetMethod(nameof(Enumerable.SelectMany), 3,
+ types => new[]
+ {
+ typeof(IEnumerable<>).MakeGenericType(types[0]),
+ typeof(Func<,>).MakeGenericType(
+ types[0], typeof(IEnumerable<>).MakeGenericType(types[1])),
+ typeof(Func<,,>).MakeGenericType(types[0], types[1], types[2])
+ });
+
+ SequenceEqual = GetMethod(nameof(Enumerable.SequenceEqual), 1,
+ types => new[]
+ {
+ typeof(IEnumerable<>).MakeGenericType(types[0]),
+ typeof(IEnumerable<>).MakeGenericType(types[0])
+ });
+
+ SingleWithoutPredicate = GetMethod(nameof(Enumerable.Single), 1, types => new[] { typeof(IEnumerable<>).MakeGenericType(types[0]) });
+
+ SingleWithPredicate = GetMethod(nameof(Enumerable.Single), 1,
+ types => new[]
+ {
+ typeof(IEnumerable<>).MakeGenericType(types[0]),
+ typeof(Func<,>).MakeGenericType(types[0], typeof(bool))
+ });
+
+ SingleOrDefaultWithoutPredicate = GetMethod(nameof(Enumerable.SingleOrDefault), 1,
+ types => new[] { typeof(IEnumerable<>).MakeGenericType(types[0]) });
+
+ SingleOrDefaultWithPredicate = GetMethod(nameof(Enumerable.SingleOrDefault), 1,
+ types => new[]
+ {
+ typeof(IEnumerable<>).MakeGenericType(types[0]),
+ typeof(Func<,>).MakeGenericType(types[0], typeof(bool))
+ });
+
+ Skip = GetMethod(nameof(Enumerable.Skip), 1,
+ types => new[]
+ {
+ typeof(IEnumerable<>).MakeGenericType(types[0]),
+ typeof(int)
+ });
+
+ SkipWhile = GetMethod(nameof(Enumerable.SkipWhile), 1,
+ types => new[]
+ {
+ typeof(IEnumerable<>).MakeGenericType(types[0]),
+ typeof(Func<,>).MakeGenericType(types[0], typeof(bool))
+ });
+
+ ToArray = GetMethod(nameof(Enumerable.ToArray), 1, types => new[] { typeof(IEnumerable<>).MakeGenericType(types[0]) });
+
+ ToList = GetMethod(nameof(Enumerable.ToList), 1, types => new[] { typeof(IEnumerable<>).MakeGenericType(types[0]) });
+
+ Take = GetMethod(nameof(Enumerable.Take), 1,
+ types => new[]
+ {
+ typeof(IEnumerable<>).MakeGenericType(types[0]),
+ typeof(int)
+ });
+
+ TakeWhile = GetMethod(nameof(Enumerable.TakeWhile), 1,
+ types => new[]
+ {
+ typeof(IEnumerable<>).MakeGenericType(types[0]),
+ typeof(Func<,>).MakeGenericType(types[0], typeof(bool))
+ });
+
+ ThenBy = GetMethod(nameof(Enumerable.ThenBy), 2,
+ types => new[]
+ {
+ typeof(IOrderedEnumerable<>).MakeGenericType(types[0]),
+ typeof(Func<,>).MakeGenericType(types[0], types[1])
+ });
+
+ ThenByDescending = GetMethod(nameof(Enumerable.ThenByDescending), 2,
+ types => new[]
+ {
+ typeof(IOrderedEnumerable<>).MakeGenericType(types[0]),
+ typeof(Func<,>).MakeGenericType(types[0], types[1])
+ });
+
+ Union = GetMethod(nameof(Enumerable.Union), 1,
+ types => new[]
+ {
+ typeof(IEnumerable<>).MakeGenericType(types[0]),
+ typeof(IEnumerable<>).MakeGenericType(types[0])
+ });
+
+ Where = GetMethod(nameof(Enumerable.Where), 1,
+ types => new[]
+ {
+ typeof(IEnumerable<>).MakeGenericType(types[0]),
+ typeof(Func<,>).MakeGenericType(types[0], typeof(bool))
+ });
+
+ var numericTypes = new[]
{
- { typeof(decimal), GetMethodWithoutSelector(enumerableMethods, nameof(Enumerable.Sum)) },
- { typeof(long), GetMethodWithoutSelector(enumerableMethods, nameof(Enumerable.Sum)) },
- { typeof(int), GetMethodWithoutSelector(enumerableMethods, nameof(Enumerable.Sum)) },
- { typeof(double), GetMethodWithoutSelector(enumerableMethods, nameof(Enumerable.Sum)) },
- { typeof(float), GetMethodWithoutSelector(enumerableMethods, nameof(Enumerable.Sum)) },
- { typeof(decimal?), GetMethodWithoutSelector(enumerableMethods, nameof(Enumerable.Sum)) },
- { typeof(long?), GetMethodWithoutSelector(enumerableMethods, nameof(Enumerable.Sum)) },
- { typeof(int?), GetMethodWithoutSelector(enumerableMethods, nameof(Enumerable.Sum)) },
- { typeof(double?), GetMethodWithoutSelector(enumerableMethods, nameof(Enumerable.Sum)) },
- { typeof(float?), GetMethodWithoutSelector(enumerableMethods, nameof(Enumerable.Sum)) }
+ typeof(int),
+ typeof(int?),
+ typeof(long),
+ typeof(long?),
+ typeof(float),
+ typeof(float?),
+ typeof(double),
+ typeof(double?),
+ typeof(decimal),
+ typeof(decimal?)
};
- SumWithSelectorMethods = new Dictionary
- {
- { typeof(decimal), GetMethodWithSelector(enumerableMethods, nameof(Enumerable.Sum)) },
- { typeof(long), GetMethodWithSelector(enumerableMethods, nameof(Enumerable.Sum)) },
- { typeof(int), GetMethodWithSelector(enumerableMethods, nameof(Enumerable.Sum)) },
- { typeof(double), GetMethodWithSelector(enumerableMethods, nameof(Enumerable.Sum)) },
- { typeof(float), GetMethodWithSelector(enumerableMethods, nameof(Enumerable.Sum)) },
- { typeof(decimal?), GetMethodWithSelector(enumerableMethods, nameof(Enumerable.Sum)) },
- { typeof(long?), GetMethodWithSelector(enumerableMethods, nameof(Enumerable.Sum)) },
- { typeof(int?), GetMethodWithSelector(enumerableMethods, nameof(Enumerable.Sum)) },
- { typeof(double?), GetMethodWithSelector(enumerableMethods, nameof(Enumerable.Sum)) },
- { typeof(float?), GetMethodWithSelector(enumerableMethods, nameof(Enumerable.Sum)) }
- };
+ AverageWithoutSelectorMethods = new Dictionary();
+ AverageWithSelectorMethods = new Dictionary();
+ MaxWithoutSelectorMethods = new Dictionary();
+ MaxWithSelectorMethods = new Dictionary();
+ MinWithoutSelectorMethods = new Dictionary();
+ MinWithSelectorMethods = new Dictionary();
+ SumWithoutSelectorMethods = new Dictionary();
+ SumWithSelectorMethods = new Dictionary();
- AverageWithoutSelectorMethods = new Dictionary
+ foreach (var type in numericTypes)
{
- { typeof(decimal), GetMethodWithoutSelector(enumerableMethods, nameof(Enumerable.Average)) },
- { typeof(long), GetMethodWithoutSelector(enumerableMethods, nameof(Enumerable.Average)) },
- { typeof(int), GetMethodWithoutSelector(enumerableMethods, nameof(Enumerable.Average)) },
- { typeof(double), GetMethodWithoutSelector(enumerableMethods, nameof(Enumerable.Average)) },
- { typeof(float), GetMethodWithoutSelector(enumerableMethods, nameof(Enumerable.Average)) },
- { typeof(decimal?), GetMethodWithoutSelector(enumerableMethods, nameof(Enumerable.Average)) },
- { typeof(long?), GetMethodWithoutSelector(enumerableMethods, nameof(Enumerable.Average)) },
- { typeof(int?), GetMethodWithoutSelector(enumerableMethods, nameof(Enumerable.Average)) },
- { typeof(double?), GetMethodWithoutSelector(enumerableMethods, nameof(Enumerable.Average)) },
- { typeof(float?), GetMethodWithoutSelector(enumerableMethods, nameof(Enumerable.Average)) }
- };
-
- AverageWithSelectorMethods = new Dictionary
- {
- { typeof(decimal), GetMethodWithSelector(enumerableMethods, nameof(Enumerable.Average)) },
- { typeof(long), GetMethodWithSelector(enumerableMethods, nameof(Enumerable.Average)) },
- { typeof(int), GetMethodWithSelector(enumerableMethods, nameof(Enumerable.Average)) },
- { typeof(double), GetMethodWithSelector(enumerableMethods, nameof(Enumerable.Average)) },
- { typeof(float), GetMethodWithSelector(enumerableMethods, nameof(Enumerable.Average)) },
- { typeof(decimal?), GetMethodWithSelector(enumerableMethods, nameof(Enumerable.Average)) },
- { typeof(long?), GetMethodWithSelector(enumerableMethods, nameof(Enumerable.Average)) },
- { typeof(int?), GetMethodWithSelector(enumerableMethods, nameof(Enumerable.Average)) },
- { typeof(double?), GetMethodWithSelector(enumerableMethods, nameof(Enumerable.Average)) },
- { typeof(float?), GetMethodWithSelector(enumerableMethods, nameof(Enumerable.Average)) }
- };
-
- MaxWithoutSelectorMethods = new Dictionary
- {
- { typeof(decimal), GetMethodWithoutSelector(enumerableMethods, nameof(Queryable.Max)) },
- { typeof(long), GetMethodWithoutSelector(enumerableMethods, nameof(Queryable.Max)) },
- { typeof(int), GetMethodWithoutSelector(enumerableMethods, nameof(Queryable.Max)) },
- { typeof(double), GetMethodWithoutSelector(enumerableMethods, nameof(Queryable.Max)) },
- { typeof(float), GetMethodWithoutSelector(enumerableMethods, nameof(Queryable.Max)) },
- { typeof(decimal?), GetMethodWithoutSelector(enumerableMethods, nameof(Queryable.Max)) },
- { typeof(long?), GetMethodWithoutSelector(enumerableMethods, nameof(Queryable.Max)) },
- { typeof(int?), GetMethodWithoutSelector(enumerableMethods, nameof(Queryable.Max)) },
- { typeof(double?), GetMethodWithoutSelector(enumerableMethods, nameof(Queryable.Max)) },
- { typeof(float?), GetMethodWithoutSelector(enumerableMethods, nameof(Queryable.Max)) }
- };
-
- MaxWithSelectorMethods = new Dictionary
- {
- { typeof(decimal), GetMethodWithSelector(enumerableMethods, nameof(Queryable.Max)) },
- { typeof(long), GetMethodWithSelector(enumerableMethods, nameof(Queryable.Max)) },
- { typeof(int), GetMethodWithSelector(enumerableMethods, nameof(Queryable.Max)) },
- { typeof(double), GetMethodWithSelector(enumerableMethods, nameof(Queryable.Max)) },
- { typeof(float), GetMethodWithSelector(enumerableMethods, nameof(Queryable.Max)) },
- { typeof(decimal?), GetMethodWithSelector(enumerableMethods, nameof(Queryable.Max)) },
- { typeof(long?), GetMethodWithSelector(enumerableMethods, nameof(Queryable.Max)) },
- { typeof(int?), GetMethodWithSelector(enumerableMethods, nameof(Queryable.Max)) },
- { typeof(double?), GetMethodWithSelector(enumerableMethods, nameof(Queryable.Max)) },
- { typeof(float?), GetMethodWithSelector(enumerableMethods, nameof(Queryable.Max)) }
- };
-
- MinWithoutSelectorMethods = new Dictionary
- {
- { typeof(decimal), GetMethodWithoutSelector(enumerableMethods, nameof(Queryable.Min)) },
- { typeof(long), GetMethodWithoutSelector(enumerableMethods, nameof(Queryable.Min)) },
- { typeof(int), GetMethodWithoutSelector(enumerableMethods, nameof(Queryable.Min)) },
- { typeof(double), GetMethodWithoutSelector(enumerableMethods, nameof(Queryable.Min)) },
- { typeof(float), GetMethodWithoutSelector(enumerableMethods, nameof(Queryable.Min)) },
- { typeof(decimal?), GetMethodWithoutSelector(enumerableMethods, nameof(Queryable.Min)) },
- { typeof(long?), GetMethodWithoutSelector(enumerableMethods, nameof(Queryable.Min)) },
- { typeof(int?), GetMethodWithoutSelector(enumerableMethods, nameof(Queryable.Min)) },
- { typeof(double?), GetMethodWithoutSelector(enumerableMethods, nameof(Queryable.Min)) },
- { typeof(float?), GetMethodWithoutSelector(enumerableMethods, nameof(Queryable.Min)) }
- };
-
- MinWithSelectorMethods = new Dictionary
- {
- { typeof(decimal), GetMethodWithSelector(enumerableMethods, nameof(Queryable.Min)) },
- { typeof(long), GetMethodWithSelector(enumerableMethods, nameof(Queryable.Min)) },
- { typeof(int), GetMethodWithSelector(enumerableMethods, nameof(Queryable.Min)) },
- { typeof(double), GetMethodWithSelector(enumerableMethods, nameof(Queryable.Min)) },
- { typeof(float), GetMethodWithSelector(enumerableMethods, nameof(Queryable.Min)) },
- { typeof(decimal?), GetMethodWithSelector(enumerableMethods, nameof(Queryable.Min)) },
- { typeof(long?), GetMethodWithSelector(enumerableMethods, nameof(Queryable.Min)) },
- { typeof(int?), GetMethodWithSelector(enumerableMethods, nameof(Queryable.Min)) },
- { typeof(double?), GetMethodWithSelector(enumerableMethods, nameof(Queryable.Min)) },
- { typeof(float?), GetMethodWithSelector(enumerableMethods, nameof(Queryable.Min)) }
- };
-
- static MethodInfo GetMethodWithoutSelector(List enumerableMethods, string methodName)
- => enumerableMethods.Single(
- mi => mi.Name == methodName
- && mi.GetParameters().Length == 1
- && mi.GetParameters()[0].ParameterType.GetGenericArguments()[0] == typeof(T));
-
- static MethodInfo GetMethodWithSelector(List enumerableMethods, string methodName)
- => enumerableMethods.Single(
- mi => mi.Name == methodName
- && mi.GetParameters().Length == 2
- && IsSelector(mi.GetParameters()[1].ParameterType));
-
- static bool IsFunc(Type type, int funcGenericArgs = 2)
- => type.IsGenericType
- && (funcGenericArgs == 1 && type.GetGenericTypeDefinition() == typeof(Func<>)
- || funcGenericArgs == 2 && type.GetGenericTypeDefinition() == typeof(Func<,>)
- || funcGenericArgs == 3 && type.GetGenericTypeDefinition() == typeof(Func<,,>));
-
- static bool IsSelector(Type type)
- => type.IsGenericType
- && type.GetGenericTypeDefinition() == typeof(Func<,>)
- && type.GetGenericArguments()[1] == typeof(T);
+ AverageWithoutSelectorMethods[type] = GetMethod(
+ nameof(Enumerable.Average), 0, types => new[] { typeof(IEnumerable<>).MakeGenericType(type) });
+ AverageWithSelectorMethods[type] = GetMethod(
+ nameof(Enumerable.Average), 1, types => new[] {
+ typeof(IEnumerable<>).MakeGenericType(types[0]),
+ typeof(Func<,>).MakeGenericType(types[0], type)
+ });
+ MaxWithoutSelectorMethods[type] = GetMethod(
+ nameof(Enumerable.Max), 0, types => new[] { typeof(IEnumerable<>).MakeGenericType(type) });
+ MaxWithSelectorMethods[type] = GetMethod(
+ nameof(Enumerable.Max), 1, types => new[] {
+ typeof(IEnumerable<>).MakeGenericType(types[0]),
+ typeof(Func<,>).MakeGenericType(types[0], type)
+ });
+ MinWithoutSelectorMethods[type] = GetMethod(
+ nameof(Enumerable.Min), 0, types => new[] { typeof(IEnumerable<>).MakeGenericType(type) });
+ MinWithSelectorMethods[type] = GetMethod(
+ nameof(Enumerable.Min), 1, types => new[] {
+ typeof(IEnumerable<>).MakeGenericType(types[0]),
+ typeof(Func<,>).MakeGenericType(types[0], type)
+ });
+ SumWithoutSelectorMethods[type] = GetMethod(
+ nameof(Enumerable.Sum), 0, types => new[] { typeof(IEnumerable<>).MakeGenericType(type) });
+ SumWithSelectorMethods[type] = GetMethod(
+ nameof(Enumerable.Sum), 1, types => new[] {
+ typeof(IEnumerable<>).MakeGenericType(types[0]),
+ typeof(Func<,>).MakeGenericType(types[0], type)
+ });
+ }
+
+ MethodInfo GetMethod(string name, int genericParameterCount, Func parameterGenerator)
+ => queryableMethodGroups[name].Single(
+ mi => ((genericParameterCount == 0 && !mi.IsGenericMethod)
+ || (mi.IsGenericMethod && mi.GetGenericArguments().Length == genericParameterCount))
+ && mi.GetParameters().Select(e => e.ParameterType).SequenceEqual(
+ parameterGenerator(mi.IsGenericMethod ? mi.GetGenericArguments() : Array.Empty())));
}
}
-}
+}
\ No newline at end of file