IGNITE-4385 .NET: Allow inline AsCacheQueryable in LINQ
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/c040c376 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/c040c376 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/c040c376 Branch: refs/heads/ignite-2.0 Commit: c040c3767b3962e125aac81cb0a6c25fa565cec4 Parents: 781e5b7 Author: Pavel Tupitsyn <[email protected]> Authored: Fri Dec 23 19:07:17 2016 +0300 Committer: Pavel Tupitsyn <[email protected]> Committed: Fri Dec 23 19:07:17 2016 +0300 ---------------------------------------------------------------------- .../Cache/Query/CacheLinqTest.cs | 51 ++++++++++++++++++-- .../Apache.Ignite.Linq/Impl/ExpressionWalker.cs | 8 +++ 2 files changed, 56 insertions(+), 3 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/c040c376/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheLinqTest.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheLinqTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheLinqTest.cs index e74f09f..798e7e8 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheLinqTest.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheLinqTest.cs @@ -425,6 +425,19 @@ namespace Apache.Ignite.Core.Tests.Cache.Query } /// <summary> + /// Tests the cross cache join. + /// </summary> + [Test] + public void TestCrossCacheJoinInline() + { + var res = GetPersonCache().AsCacheQueryable().Join(GetRoleCache().AsCacheQueryable(), + person => person.Key, role => role.Key.Foo, (person, role) => role).ToArray(); + + Assert.AreEqual(RoleCount, res.Length); + Assert.AreEqual(101, res[0].Key.Bar); + } + + /// <summary> /// Tests the multi cache join. /// </summary> [Test] @@ -516,7 +529,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Query } /// <summary> - /// Tests the multiple from. + /// Tests query with multiple from clause. /// </summary> [Test] public void TestMultipleFrom() @@ -539,6 +552,23 @@ namespace Apache.Ignite.Core.Tests.Cache.Query } /// <summary> + /// Tests query with multiple from clause with inline query sources. + /// </summary> + [Test] + public void TestMultipleFromInline() + { + var filtered = + from person in GetPersonCache().AsCacheQueryable() + from role in GetRoleCache().AsCacheQueryable() + where person.Key == role.Key.Foo + select new {Person = person.Value.Name, Role = role.Value.Name}; + + var res = filtered.ToArray(); + + Assert.AreEqual(RoleCount, res.Length); + } + + /// <summary> /// Tests the join of a table to itself. /// </summary> [Test] @@ -557,6 +587,18 @@ namespace Apache.Ignite.Core.Tests.Cache.Query } /// <summary> + /// Tests the join of a table to itself with inline queryable. + /// </summary> + [Test] + public void TestSelfJoinInline() + { + var qry = GetPersonCache().AsCacheQueryable().Join(GetPersonCache().AsCacheQueryable(), + x => x.Value.Age, x => x.Key, (x, y) => x.Key); + + Assert.AreEqual(PersonCount, qry.ToArray().Distinct().Count()); + } + + /// <summary> /// Tests the group by. /// </summary> [Test] @@ -729,9 +771,11 @@ namespace Apache.Ignite.Core.Tests.Cache.Query var persons = GetPersonCache().AsCacheQueryable(); // Invalid dateTime - var now = DateTime.Now; // ReSharper disable once ReturnValueOfPureMethodIsNotUsed - Assert.Throws<InvalidOperationException>(() => roles.Where(x => x.Value.Date > now).ToArray()); + var ex = Assert.Throws<InvalidOperationException>(() => + roles.Where(x => x.Value.Date > DateTime.Now).ToArray()); + Assert.AreEqual("DateTime is not UTC. Only UTC DateTime can be used for interop with other platforms.", + ex.Message); // Test retrieval var dates = roles.OrderBy(x => x.Value.Date).Select(x => x.Value.Date); @@ -741,6 +785,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Query // Filtering Assert.AreEqual(1, persons.Count(x => x.Value.Birthday == StartDateTime)); Assert.AreEqual(PersonCount, persons.Count(x => x.Value.Birthday >= StartDateTime)); + Assert.Greater(persons.Count(x => x.Value.Birthday > DateTime.UtcNow), 1); // Joins var join = http://git-wip-us.apache.org/repos/asf/ignite/blob/c040c376/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/ExpressionWalker.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/ExpressionWalker.cs b/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/ExpressionWalker.cs index a447bf5..4407f96 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/ExpressionWalker.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/ExpressionWalker.cs @@ -99,6 +99,14 @@ namespace Apache.Ignite.Linq.Impl return queryable; } + var callExpr = expression as MethodCallExpression; + + if (callExpr != null) + { + // This is usually a nested query with a call to AsCacheQueryable(). + return (ICacheQueryableInternal) Expression.Lambda(callExpr).Compile().DynamicInvoke(); + } + if (throwWhenNotFound) throw new NotSupportedException("Unexpected query source: " + expression);
