Skip to content

Commit 93d93d7

Browse files
authored
Add Concat, Union, Except and Intersect (#506)
1 parent ed90b13 commit 93d93d7

10 files changed

+118
-8
lines changed

src/System.Linq.Dynamic.Core/DynamicQueryableExtensions.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ namespace System.Linq.Dynamic.Core
2626
public static class DynamicQueryableExtensions
2727
{
2828
#if !(WINDOWS_APP45x || SILVERLIGHT)
29-
private static readonly TraceSource TraceSource = new TraceSource(typeof(DynamicQueryableExtensions).Name);
29+
private static readonly TraceSource TraceSource = new TraceSource(nameof(DynamicQueryableExtensions));
3030
#endif
3131

3232
private static Expression OptimizeExpression(Expression expression)
@@ -76,7 +76,7 @@ public static object Aggregate([NotNull] this IQueryable source, [NotNull] strin
7676
{
7777
ParameterInfo lastParameter = m.GetParameters().LastOrDefault();
7878

79-
return lastParameter != null ? TypeHelper.GetUnderlyingType(lastParameter.ParameterType) == property.PropertyType : false;
79+
return lastParameter != null && TypeHelper.GetUnderlyingType(lastParameter.ParameterType) == property.PropertyType;
8080
});
8181

8282
// Sum, Average

src/System.Linq.Dynamic.Core/Parser/ExpressionParser.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1923,7 +1923,7 @@ Expression ParseEnumerable(Expression instance, Type elementType, string methodN
19231923
}
19241924
else
19251925
{
1926-
if (new[] { "Contains", "Take", "Skip", "DefaultIfEmpty" }.Contains(methodName))
1926+
if (new[] { "Concat", "Contains", "DefaultIfEmpty", "Except", "Intersect", "Skip", "Take", "Union" }.Contains(methodName))
19271927
{
19281928
args = new[] { instance, args[0] };
19291929
}

src/System.Linq.Dynamic.Core/Parser/SupportedMethods/IEnumerableSignatures.cs

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
namespace System.Linq.Dynamic.Core.Parser.SupportedMethods
1+
using System.Collections;
2+
3+
namespace System.Linq.Dynamic.Core.Parser.SupportedMethods
24
{
35
internal interface IEnumerableSignatures
46
{
@@ -17,18 +19,21 @@ internal interface IEnumerableSignatures
1719
void Average(long selector);
1820
void Cast(string type);
1921
void Cast(Type type);
22+
void Concat(IEnumerable enumerable);
2023
void Contains(object selector);
2124
void Count();
2225
void Count(bool predicate);
2326
void DefaultIfEmpty();
2427
void DefaultIfEmpty(object defaultValue);
2528
void Distinct();
29+
void Except(IEnumerable enumerable);
2630
void First();
2731
void First(bool predicate);
2832
void FirstOrDefault();
2933
void FirstOrDefault(bool predicate);
3034
void GroupBy(object keySelector);
3135
void GroupBy(object keySelector, object elementSelector);
36+
void Intersect(IEnumerable enumerable);
3237
void Last();
3338
void Last(bool predicate);
3439
void LastOrDefault();
@@ -63,6 +68,7 @@ internal interface IEnumerableSignatures
6368
void TakeWhile(bool predicate);
6469
void ThenBy(object selector);
6570
void ThenByDescending(object selector);
71+
void Union(IEnumerable enumerable);
6672
void Where(bool predicate);
6773

6874
// Executors

src/System.Linq.Dynamic.Core/Parser/SupportedMethods/IQueryableSignatures.cs

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
namespace System.Linq.Dynamic.Core.Parser.SupportedMethods
1+
using System.Collections;
2+
3+
namespace System.Linq.Dynamic.Core.Parser.SupportedMethods
24
{
35
internal interface IQueryableSignatures
46
{
@@ -15,19 +17,22 @@ internal interface IQueryableSignatures
1517
void Average(int selector);
1618
void Average(long? selector);
1719
void Average(long selector);
20+
void Concat(IEnumerable enumerable);
1821
void Cast(string type);
1922
void Cast(Type type);
2023
void Count();
2124
void Count(bool predicate);
2225
void DefaultIfEmpty();
2326
void DefaultIfEmpty(object defaultValue);
2427
void Distinct();
28+
void Except(IEnumerable enumerable);
2529
void First();
2630
void First(bool predicate);
2731
void FirstOrDefault();
2832
void FirstOrDefault(bool predicate);
2933
void GroupBy(object keySelector);
3034
void GroupBy(object keySelector, object elementSelector);
35+
void Intersect(IEnumerable enumerable);
3136
void Last();
3237
void Last(bool predicate);
3338
void LastOrDefault();
@@ -62,6 +67,7 @@ internal interface IQueryableSignatures
6267
void TakeWhile(bool predicate);
6368
void ThenBy(object selector);
6469
void ThenByDescending(object selector);
70+
void Union(IEnumerable enumerable);
6571
void Where(bool predicate);
6672
}
6773
}

test/System.Linq.Dynamic.Core.Tests/Parser/ExpressionParserTests.TypeAccess.cs

-2
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,6 @@ public void ParseTypeAccess_Via_Constructor_String_To_DateTime_Valid()
5454

5555
[Theory]
5656
[InlineData(null)]
57-
[InlineData(1.1d)]
58-
[InlineData(1.1f)]
5957
[InlineData("\"abc\"")]
6058
public void ParseTypeAccess_Via_Constructor_Any_To_DateTime_Invalid(object any)
6159
{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using System.Collections.Generic;
2+
using FluentAssertions;
3+
using Xunit;
4+
5+
namespace System.Linq.Dynamic.Core.Tests
6+
{
7+
public partial class QueryableTests
8+
{
9+
[Fact]
10+
public void Concat_Dynamic_ListOfStrings()
11+
{
12+
// Arrange
13+
var list1 = new List<bool> { true };
14+
var list2 = new List<string> { "User3", "User4" };
15+
var list3 = new List<string> { "User5", "User6", "User7" };
16+
17+
// Act
18+
var testQuery = list1.AsQueryable().Select("@0.Concat(@1).ToList()", list2, list3);
19+
20+
// Assert
21+
var result = testQuery.ToDynamicArray<List<string>>();
22+
result.First().Should().BeEquivalentTo(list2.Concat(list3));
23+
}
24+
}
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using System.Collections.Generic;
2+
using FluentAssertions;
3+
using Xunit;
4+
5+
namespace System.Linq.Dynamic.Core.Tests
6+
{
7+
public partial class QueryableTests
8+
{
9+
[Fact]
10+
public void Except_Dynamic_ListOfStrings()
11+
{
12+
// Arrange
13+
var list1 = new List<bool> { true };
14+
var list2 = new List<string> { "User3", "User4" };
15+
var list3 = new List<string> { "User3", "User6", "User7" };
16+
17+
// Act
18+
var testQuery = list1.AsQueryable().Select("@0.Except(@1).ToList()", list2, list3);
19+
20+
// Assert
21+
var result = testQuery.ToDynamicArray<List<string>>();
22+
result.First().Should().BeEquivalentTo(list2.Except(list3));
23+
}
24+
}
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using System.Collections.Generic;
2+
using FluentAssertions;
3+
using Xunit;
4+
5+
namespace System.Linq.Dynamic.Core.Tests
6+
{
7+
public partial class QueryableTests
8+
{
9+
[Fact]
10+
public void Intersect_Dynamic_ListOfStrings()
11+
{
12+
// Arrange
13+
var list1 = new List<bool> { true };
14+
var list2 = new List<string> { "User3", "User4" };
15+
var list3 = new List<string> { "User3", "User6", "User7" };
16+
17+
// Act
18+
var testQuery = list1.AsQueryable().Select("@0.Intersect(@1).ToList()", list2, list3);
19+
20+
// Assert
21+
var result = testQuery.ToDynamicArray<List<string>>();
22+
result.First().Should().BeEquivalentTo(list2.Intersect(list3));
23+
}
24+
}
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using System.Collections.Generic;
2+
using FluentAssertions;
3+
using Xunit;
4+
5+
namespace System.Linq.Dynamic.Core.Tests
6+
{
7+
public partial class QueryableTests
8+
{
9+
[Fact]
10+
public void Union_Dynamic_ListOfStrings()
11+
{
12+
// Arrange
13+
var list1 = new List<bool> { true };
14+
var list2 = new List<string> { "User3", "User4" };
15+
var list3 = new List<string> { "User3", "User6", "User7" };
16+
17+
// Act
18+
var testQuery = list1.AsQueryable().Select("@0.Union(@1).ToList()", list2, list3);
19+
20+
// Assert
21+
var result = testQuery.ToDynamicArray<List<string>>();
22+
result.First().Should().BeEquivalentTo(list2.Union(list3));
23+
}
24+
}
25+
}

version.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<Project>
22
<PropertyGroup>
3-
<PatchVersion>9</PatchVersion>
3+
<PatchVersion>10-preview-01</PatchVersion>
44
</PropertyGroup>
55
</Project>

0 commit comments

Comments
 (0)