@@ -200,6 +200,46 @@ public static int Count([NotNull] this IQueryable source, [NotNull] LambdaExpres
200
200
}
201
201
#endregion Count
202
202
203
+ #region DefaultIfEmpty
204
+ private static readonly MethodInfo _defaultIfEmpty = GetMethod ( nameof ( Queryable . DefaultIfEmpty ) ) ;
205
+ private static readonly MethodInfo _defaultIfEmptyWithParam = GetMethod ( nameof ( Queryable . DefaultIfEmpty ) , 1 ) ;
206
+
207
+ /// <summary>
208
+ /// Returns the elements of the specified sequence or the type parameter's default value in a singleton collection if the sequence is empty.
209
+ /// </summary>
210
+ /// <param name="source">The <see cref="IQueryable"/> to return a default value for if empty.</param>
211
+ /// <example>
212
+ /// <code language="cs">
213
+ /// IQueryable queryable = employees.DefaultIfEmpty();
214
+ /// </code>
215
+ /// </example>
216
+ /// <returns>An <see cref="IQueryable"/> that contains default if source is empty; otherwise, source.</returns>
217
+ public static IQueryable DefaultIfEmpty ( [ NotNull ] this IQueryable source )
218
+ {
219
+ Check . NotNull ( source , nameof ( source ) ) ;
220
+
221
+ return CreateQuery ( _defaultIfEmpty , source ) ;
222
+ }
223
+
224
+ /// <summary>
225
+ /// Returns the elements of the specified sequence or the type parameter's default value in a singleton collection if the sequence is empty.
226
+ /// </summary>
227
+ /// <param name="source">The <see cref="IQueryable"/> to return a default value for if empty.</param>
228
+ /// <param name="defaultValue">The value to return if the sequence is empty.</param>
229
+ /// <example>
230
+ /// <code language="cs">
231
+ /// IQueryable queryable = employees.DefaultIfEmpty(new Employee());
232
+ /// </code>
233
+ /// </example>
234
+ /// <returns>An <see cref="IQueryable"/> that contains defaultValue if source is empty; otherwise, source.</returns>
235
+ public static IQueryable DefaultIfEmpty ( [ NotNull ] this IQueryable source , [ CanBeNull ] object defaultValue )
236
+ {
237
+ Check . NotNull ( source , nameof ( source ) ) ;
238
+
239
+ return CreateQuery ( _defaultIfEmptyWithParam , source , Expression . Constant ( defaultValue ) ) ;
240
+ }
241
+ #endregion
242
+
203
243
#region Distinct
204
244
private static readonly MethodInfo _distinct = GetMethod ( nameof ( Queryable . Distinct ) ) ;
205
245
@@ -219,8 +259,7 @@ public static IQueryable Distinct([NotNull] this IQueryable source)
219
259
{
220
260
Check . NotNull ( source , nameof ( source ) ) ;
221
261
222
- var optimized = OptimizeExpression ( Expression . Call ( typeof ( Queryable ) , "Distinct" , new Type [ ] { source . ElementType } , source . Expression ) ) ;
223
- return source . Provider . CreateQuery ( optimized ) ;
262
+ return CreateQuery ( _distinct , source ) ;
224
263
}
225
264
#endregion Distinct
226
265
@@ -285,6 +324,8 @@ public static dynamic First([NotNull] this IQueryable source, [NotNull] LambdaEx
285
324
#endregion First
286
325
287
326
#region FirstOrDefault
327
+ private static readonly MethodInfo _firstOrDefault = GetMethod ( nameof ( Queryable . FirstOrDefault ) ) ;
328
+
288
329
/// <summary>
289
330
/// Returns the first element of a sequence, or a default value if the sequence contains no elements.
290
331
/// </summary>
@@ -300,7 +341,6 @@ public static dynamic FirstOrDefault([NotNull] this IQueryable source)
300
341
301
342
return Execute ( _firstOrDefault , source ) ;
302
343
}
303
- private static readonly MethodInfo _firstOrDefault = GetMethod ( nameof ( Queryable . FirstOrDefault ) ) ;
304
344
305
345
/// <summary>
306
346
/// Returns the first element of a sequence that satisfies a specified condition or a default value if no such element is found.
@@ -424,8 +464,7 @@ public static IQueryable GroupBy([NotNull] this IQueryable source, [NotNull] str
424
464
425
465
var optimized = OptimizeExpression ( Expression . Call (
426
466
typeof ( Queryable ) , nameof ( Queryable . GroupBy ) ,
427
- new [ ] { source . ElementType , keyLambda . Body . Type } ,
428
- new [ ] { source . Expression , Expression . Quote ( keyLambda ) } ) ) ;
467
+ new [ ] { source . ElementType , keyLambda . Body . Type } , source . Expression , Expression . Quote ( keyLambda ) ) ) ;
429
468
430
469
return source . Provider . CreateQuery ( optimized ) ;
431
470
}
@@ -1539,7 +1578,7 @@ public static IQueryable Where([NotNull] this IQueryable source, [NotNull] strin
1539
1578
var optimized = OptimizeExpression ( Expression . Call ( typeof ( Queryable ) , "Where" , new [ ] { source . ElementType } , source . Expression , Expression . Quote ( lambda ) ) ) ;
1540
1579
return source . Provider . CreateQuery ( optimized ) ;
1541
1580
}
1542
-
1581
+
1543
1582
/// <summary>
1544
1583
/// Filters a sequence of values based on a predicate.
1545
1584
/// </summary>
@@ -1549,7 +1588,7 @@ public static IQueryable Where([NotNull] this IQueryable source, [NotNull] Lambd
1549
1588
{
1550
1589
Check . NotNull ( source , nameof ( source ) ) ;
1551
1590
Check . NotNull ( lambda , nameof ( lambda ) ) ;
1552
-
1591
+
1553
1592
var optimized = OptimizeExpression ( Expression . Call ( typeof ( Queryable ) , "Where" , new [ ] { source . ElementType } , source . Expression , Expression . Quote ( lambda ) ) ) ;
1554
1593
return source . Provider . CreateQuery ( optimized ) ;
1555
1594
}
@@ -1604,7 +1643,7 @@ private static IQueryable CreateQuery(MethodInfo operatorMethodInfo, IQueryable
1604
1643
? operatorMethodInfo . MakeGenericMethod ( source . ElementType , typeof ( object ) )
1605
1644
: operatorMethodInfo . MakeGenericMethod ( source . ElementType ) ;
1606
1645
1607
- return source . Provider . CreateQuery ( Expression . Call ( null , operatorMethodInfo , new [ ] { source . Expression , expression } ) ) ;
1646
+ return source . Provider . CreateQuery ( Expression . Call ( null , operatorMethodInfo , source . Expression , expression ) ) ;
1608
1647
}
1609
1648
1610
1649
private static object Execute ( MethodInfo operatorMethodInfo , IQueryable source )
@@ -1638,7 +1677,7 @@ private static object Execute(MethodInfo operatorMethodInfo, IQueryable source,
1638
1677
? operatorMethodInfo . MakeGenericMethod ( source . ElementType , typeof ( object ) )
1639
1678
: operatorMethodInfo . MakeGenericMethod ( source . ElementType ) ;
1640
1679
1641
- var optimized = OptimizeExpression ( Expression . Call ( null , operatorMethodInfo , new [ ] { source . Expression , expression } ) ) ;
1680
+ var optimized = OptimizeExpression ( Expression . Call ( null , operatorMethodInfo , source . Expression , expression ) ) ;
1642
1681
return source . Provider . Execute ( optimized ) ;
1643
1682
}
1644
1683
@@ -1651,15 +1690,15 @@ private static TResult Execute<TResult>(MethodInfo operatorMethodInfo, IQueryabl
1651
1690
? operatorMethodInfo . MakeGenericMethod ( source . ElementType , typeof ( TResult ) )
1652
1691
: operatorMethodInfo . MakeGenericMethod ( source . ElementType ) ;
1653
1692
1654
- var optimized = OptimizeExpression ( Expression . Call ( null , operatorMethodInfo , new [ ] { source . Expression , expression } ) ) ;
1693
+ var optimized = OptimizeExpression ( Expression . Call ( null , operatorMethodInfo , source . Expression , expression ) ) ;
1655
1694
return source . Provider . Execute < TResult > ( optimized ) ;
1656
1695
}
1657
1696
1658
1697
private static MethodInfo GetMethod < TResult > ( string name , int parameterCount = 0 , Func < MethodInfo , bool > predicate = null ) =>
1659
- GetMethod ( name , parameterCount , mi => ( mi . ReturnType == typeof ( TResult ) ) && ( ( predicate == null ) || predicate ( mi ) ) ) ;
1698
+ GetMethod ( name , parameterCount , mi => mi . ReturnType == typeof ( TResult ) && ( predicate == null || predicate ( mi ) ) ) ;
1660
1699
1661
1700
private static MethodInfo GetMethod ( string name , int parameterCount = 0 , Func < MethodInfo , bool > predicate = null ) =>
1662
- typeof ( Queryable ) . GetTypeInfo ( ) . GetDeclaredMethods ( name ) . Single ( mi => ( mi . GetParameters ( ) . Length == parameterCount + 1 ) && ( ( predicate == null ) || predicate ( mi ) ) ) ;
1701
+ typeof ( Queryable ) . GetTypeInfo ( ) . GetDeclaredMethods ( name ) . Single ( mi => mi . GetParameters ( ) . Length == parameterCount + 1 && ( predicate == null || predicate ( mi ) ) ) ;
1663
1702
#endregion Private Helpers
1664
1703
}
1665
1704
}
0 commit comments