Skip to content

Commit ebb6b94

Browse files
authored
Fix IReadOnlyDictionary<,> (#495)
1 parent 44d6b63 commit ebb6b94

File tree

3 files changed

+57
-22
lines changed

3 files changed

+57
-22
lines changed

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -1754,7 +1754,7 @@ Expression ParseMemberAccess(Type type, Expression expression)
17541754
Expression ParseEnumerable(Expression instance, Type elementType, string methodName, int errorPos, Type type)
17551755
{
17561756
bool isQueryable = TypeHelper.FindGenericType(typeof(IQueryable<>), type) != null;
1757-
bool isDictionary = TypeHelper.FindGenericType(typeof(IDictionary<,>), type) != null;
1757+
bool isDictionary = TypeHelper.IsDictionary(type);
17581758

17591759
var oldParent = _parent;
17601760

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

+17-3
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,13 @@ public static Type FindGenericType(Type generic, Type type)
1717

1818
if (generic.GetTypeInfo().IsInterface)
1919
{
20-
foreach (Type intfType in type.GetInterfaces())
20+
foreach (Type interfaceType in type.GetInterfaces())
2121
{
22-
Type found = FindGenericType(generic, intfType);
23-
if (found != null) return found;
22+
Type found = FindGenericType(generic, interfaceType);
23+
if (found != null)
24+
{
25+
return found;
26+
}
2427
}
2528
}
2629

@@ -440,5 +443,16 @@ public static object ParseEnum(string value, Type type)
440443

441444
return null;
442445
}
446+
447+
public static bool IsDictionary(Type type)
448+
{
449+
return
450+
FindGenericType(typeof(IDictionary<,>), type) != null ||
451+
#if NET35 || NET40
452+
false;
453+
#else
454+
FindGenericType(typeof(IReadOnlyDictionary<,>), type) != null;
455+
#endif
456+
}
443457
}
444458
}

test/System.Linq.Dynamic.Core.Tests/MikArea/Dictionary.cs

+39-18
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
using System.Collections.Generic;
2-
using System.Dynamic;
1+
using System.Collections.Concurrent;
2+
using System.Collections.Generic;
3+
using System.Collections.ObjectModel;
34
using System.Linq.Expressions;
45
using FluentAssertions;
56
using NFluent;
@@ -13,6 +14,7 @@ public class Customer
1314
{
1415
public string City { get; set; }
1516
public Dictionary<string, Order> Orders { get; set; }
17+
public IReadOnlyDictionary<string, Order> ReadOnlyOrders { get; set; }
1618
public string CompanyName { get; set; }
1719
public string Phone { get; set; }
1820
}
@@ -22,13 +24,32 @@ public class Order
2224
}
2325

2426
[Fact]
25-
public void Test_ContainsKey_1()
27+
public void ReadOnlyDictionary_ContainsKey_1()
2628
{
27-
var customers = new List<Customer>()
29+
var orders = new ReadOnlyDictionary<string, Order>(new Dictionary<string, Order>
2830
{
29-
new Customer() { City = "ZZZ1", CompanyName = "ZZZ", Orders = new Dictionary<string, Order>() },
30-
new Customer() { City = "ZZZ2", CompanyName = "ZZZ", Orders = new Dictionary<string, Order>() },
31-
new Customer() { City = "ZZZ3", CompanyName = "ZZZ", Orders = new Dictionary<string, Order>() }
31+
{ "TEST", new Order() }
32+
});
33+
var customers = new List<Customer>
34+
{
35+
new Customer { City = "abc", CompanyName = "ZZZ", ReadOnlyOrders = orders }
36+
};
37+
38+
var data = customers.AsQueryable()
39+
.Where("ReadOnlyOrders.ContainsKey(\"TEST\")")
40+
.ToList();
41+
42+
data.Should().HaveCount(1);
43+
}
44+
45+
[Fact]
46+
public void Dictionary_ContainsKey_1()
47+
{
48+
var customers = new List<Customer>
49+
{
50+
new Customer { City = "ZZZ1", CompanyName = "ZZZ", Orders = new Dictionary<string, Order>() },
51+
new Customer { City = "ZZZ2", CompanyName = "ZZZ", Orders = new Dictionary<string, Order>() },
52+
new Customer { City = "ZZZ3", CompanyName = "ZZZ", Orders = new Dictionary<string, Order>() }
3253
};
3354
customers.ForEach(x => x.Orders.Add(x.City + "TEST", new Order()));
3455

@@ -41,13 +62,13 @@ public void Test_ContainsKey_1()
4162
}
4263

4364
[Fact]
44-
public void Test_ContainsKey_2()
65+
public void Dictionary_ContainsKey_2()
4566
{
46-
var customers = new List<Customer>()
67+
var customers = new List<Customer>
4768
{
48-
new Customer() { City = "ZZZ1", CompanyName = "ZZZ", Orders = new Dictionary<string, Order>() },
49-
new Customer() { City = "ZZZ2", CompanyName = "ZZZ", Orders = new Dictionary<string, Order>() },
50-
new Customer() { City = "ZZZ3", CompanyName = "ZZZ", Orders = new Dictionary<string, Order>() }
69+
new Customer { City = "ZZZ1", CompanyName = "ZZZ", Orders = new Dictionary<string, Order>() },
70+
new Customer { City = "ZZZ2", CompanyName = "ZZZ", Orders = new Dictionary<string, Order>() },
71+
new Customer { City = "ZZZ3", CompanyName = "ZZZ", Orders = new Dictionary<string, Order>() }
5172
};
5273
customers.ForEach(x => x.Orders.Add(x.City + "TEST", new Order()));
5374

@@ -61,13 +82,13 @@ public void Test_ContainsKey_2()
6182
}
6283

6384
[Fact]
64-
public void Test_ContainsKey_3()
85+
public void Dictionary_ContainsKey_3()
6586
{
66-
var customers = new List<Customer>()
87+
var customers = new List<Customer>
6788
{
68-
new Customer() { City = "ZZZ1", CompanyName = "ZZZ", Orders = new Dictionary<string, Order>() },
69-
new Customer() { City = "ZZZ2", CompanyName = "ZZZ", Orders = new Dictionary<string, Order>() },
70-
new Customer() { City = "ZZZ3", CompanyName = "ZZZ", Orders = new Dictionary<string, Order>() }
89+
new Customer { City = "ZZZ1", CompanyName = "ZZZ", Orders = new Dictionary<string, Order>() },
90+
new Customer { City = "ZZZ2", CompanyName = "ZZZ", Orders = new Dictionary<string, Order>() },
91+
new Customer { City = "ZZZ3", CompanyName = "ZZZ", Orders = new Dictionary<string, Order>() }
7192
};
7293
customers.ForEach(x => x.Orders.Add(x.City + "TEST1", new Order()));
7394
customers.ForEach(x => x.Orders.Add(x.City + "TEST2", new Order()));
@@ -91,7 +112,7 @@ public void Test_ContainsKey_3()
91112
#else
92113
[Fact(Skip = "Fails in NET452 CI")]
93114
#endif
94-
public void Test_DynamicIndexCall() // https://github.com/zzzprojects/System.Linq.Dynamic.Core/issues/397
115+
public void DynamicIndexCall() // https://github.com/zzzprojects/System.Linq.Dynamic.Core/issues/397
95116
{
96117
object CreateDicParameter(string name) => new Dictionary<string, object>
97118
{

0 commit comments

Comments
 (0)