From 21112a41821511421cf76223c21596e90d06e999 Mon Sep 17 00:00:00 2001 From: maca88 Date: Thu, 11 Feb 2021 22:53:05 +0100 Subject: [PATCH 1/2] Fix Queryable.Contains method for Linq provider --- .../Async/Linq/MethodCallTests.cs | 14 ++++- .../NHSpecificTest/NH3850/MainFixture.cs | 44 +++++++++++++++ src/NHibernate.Test/Linq/MethodCallTests.cs | 14 ++++- .../NHSpecificTest/NH3850/MainFixture.cs | 55 +++++++++++++++++++ .../ProcessContains.cs | 19 ++++++- 5 files changed, 142 insertions(+), 4 deletions(-) diff --git a/src/NHibernate.Test/Async/Linq/MethodCallTests.cs b/src/NHibernate.Test/Async/Linq/MethodCallTests.cs index 1d95ad3b0dd..b3ba92bef4f 100644 --- a/src/NHibernate.Test/Async/Linq/MethodCallTests.cs +++ b/src/NHibernate.Test/Async/Linq/MethodCallTests.cs @@ -35,6 +35,18 @@ public async Task CanExecuteAnyWithArgumentsAsync() Assert.IsFalse(result); } + [Test] + public async Task CanExecuteContainsAsync() + { + var user = await (db.Users.FirstOrDefaultAsync()); + var result = db.Users.Contains(user); + Assert.That(result, Is.True); + + user = new User("test", DateTime.Now); + result = db.Users.Contains(user); + Assert.That(result, Is.False); + } + [Test] public async Task CanExecuteCountWithOrderByArgumentsAsync() { @@ -163,4 +175,4 @@ public async Task CanSelectPropertiesIntoNestedObjectArraysAsync() Assert.That(nestedNestedObjectArray[1], Is.EqualTo("ayende")); } } -} \ No newline at end of file +} diff --git a/src/NHibernate.Test/Async/NHSpecificTest/NH3850/MainFixture.cs b/src/NHibernate.Test/Async/NHSpecificTest/NH3850/MainFixture.cs index ecbd2e774d1..edb54df556f 100644 --- a/src/NHibernate.Test/Async/NHSpecificTest/NH3850/MainFixture.cs +++ b/src/NHibernate.Test/Async/NHSpecificTest/NH3850/MainFixture.cs @@ -187,6 +187,17 @@ public async Task AnyBBaseWithNameAsync() } } + [Test] + public async Task ContainsBBaseAsync() + { + using (var session = OpenSession()) + { + var item = await (session.Query().FirstAsync(dc => dc.Name == SearchName1)); + var result = session.Query().Contains(item); + Assert.That(result, Is.True); + } + } + // Non-reg case [Test] public async Task AnyCBaseAsync() @@ -213,6 +224,17 @@ public async Task AnyCBaseWithNameAsync() } } + [Test] + public async Task ContainsCBaseAsync() + { + using (var session = OpenSession()) + { + var item = await (session.Query().FirstAsync(dc => dc.Name == SearchName1)); + var result = session.Query().Contains(item); + Assert.That(result, Is.True); + } + } + // Non-reg case [Test] public async Task AnyEAsync() @@ -239,6 +261,17 @@ public async Task AnyEWithNameAsync() } } + [Test] + public async Task ContainsEAsync() + { + using (var session = OpenSession()) + { + var item = await (session.Query().FirstAsync(dc => dc.Name == SearchName1)); + var result = session.Query().Contains(item); + Assert.That(result, Is.True); + } + } + // Non-reg case [Test] public async Task AnyFAsync() @@ -291,6 +324,17 @@ public async Task AnyGBaseWithNameAsync() } } + [Test] + public async Task ContainsGBaseAsync() + { + using (var session = OpenSession()) + { + var item = await (session.Query().FirstAsync(dc => dc.Name == SearchName1)); + var result = session.Query().Contains(item); + Assert.That(result, Is.True); + } + } + // Failing case till NH-3850 is fixed [Test] public async Task AnyObjectAsync() diff --git a/src/NHibernate.Test/Linq/MethodCallTests.cs b/src/NHibernate.Test/Linq/MethodCallTests.cs index 1ced894c85f..c330b0944da 100644 --- a/src/NHibernate.Test/Linq/MethodCallTests.cs +++ b/src/NHibernate.Test/Linq/MethodCallTests.cs @@ -23,6 +23,18 @@ public void CanExecuteAnyWithArguments() Assert.IsFalse(result); } + [Test] + public void CanExecuteContains() + { + var user = db.Users.FirstOrDefault(); + var result = db.Users.Contains(user); + Assert.That(result, Is.True); + + user = new User("test", DateTime.Now); + result = db.Users.Contains(user); + Assert.That(result, Is.False); + } + [Test] public void CanExecuteCountWithOrderByArguments() { @@ -151,4 +163,4 @@ public void CanSelectPropertiesIntoNestedObjectArrays() Assert.That(nestedNestedObjectArray[1], Is.EqualTo("ayende")); } } -} \ No newline at end of file +} diff --git a/src/NHibernate.Test/NHSpecificTest/NH3850/MainFixture.cs b/src/NHibernate.Test/NHSpecificTest/NH3850/MainFixture.cs index 448c83a63dc..1996d943be9 100644 --- a/src/NHibernate.Test/NHSpecificTest/NH3850/MainFixture.cs +++ b/src/NHibernate.Test/NHSpecificTest/NH3850/MainFixture.cs @@ -194,6 +194,17 @@ public void AnyBBaseWithName() } } + [Test] + public void ContainsBBase() + { + using (var session = OpenSession()) + { + var item = session.Query().First(dc => dc.Name == SearchName1); + var result = session.Query().Contains(item); + Assert.That(result, Is.True); + } + } + // Non-reg case [Test] public void AnyCBase() @@ -220,6 +231,17 @@ public void AnyCBaseWithName() } } + [Test] + public void ContainsCBase() + { + using (var session = OpenSession()) + { + var item = session.Query().First(dc => dc.Name == SearchName1); + var result = session.Query().Contains(item); + Assert.That(result, Is.True); + } + } + // Non-reg case [Test] public void AnyE() @@ -246,6 +268,17 @@ public void AnyEWithName() } } + [Test] + public void ContainsE() + { + using (var session = OpenSession()) + { + var item = session.Query().First(dc => dc.Name == SearchName1); + var result = session.Query().Contains(item); + Assert.That(result, Is.True); + } + } + // Non-reg case [Test] public void AnyF() @@ -272,6 +305,17 @@ public void AnyFWithName() } } + [Test] + public void ContainsF() + { + using (var session = OpenSession()) + { + var item = new DomainClassF() {Id = -1}; + var result = session.Query().Contains(item); + Assert.That(result, Is.False); + } + } + // Non-reg case [Test] public void AnyGBase() @@ -298,6 +342,17 @@ public void AnyGBaseWithName() } } + [Test] + public void ContainsGBase() + { + using (var session = OpenSession()) + { + var item = session.Query().First(dc => dc.Name == SearchName1); + var result = session.Query().Contains(item); + Assert.That(result, Is.True); + } + } + // Failing case till NH-3850 is fixed [Test] public void AnyObject() diff --git a/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessContains.cs b/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessContains.cs index 169b1211eb5..e8432cfa629 100644 --- a/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessContains.cs +++ b/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessContains.cs @@ -1,5 +1,8 @@ -using System.Collections; +using System; +using System.Collections; +using System.Collections.Generic; using System.Linq; +using System.Linq.Expressions; using NHibernate.Hql.Ast; using Remotion.Linq.Clauses.ResultOperators; @@ -37,7 +40,19 @@ public void Process(ContainsResultOperator resultOperator, QueryModelVisitor que tree.AddWhereClause(tree.TreeBuilder.Equality( tree.TreeBuilder.Ident(GetFromAlias(tree.Root).AstNode.Text), itemExpression)); - tree.SetRoot(tree.TreeBuilder.Exists((HqlQuery)tree.Root)); + if (tree.IsRoot) + { + tree.AddTakeClause(tree.TreeBuilder.Constant(1)); + Expression, bool>> x = l => l.Any(); + tree.AddListTransformer(x); + + Expression, bool>> px = l => l.Any(r => r); + tree.AddPostExecuteTransformer(px); + } + else + { + tree.SetRoot(tree.TreeBuilder.Exists((HqlQuery) tree.Root)); + } } else { From 7eec7c7df0e9915ed490435f29364df3cc2fcf2a Mon Sep 17 00:00:00 2001 From: maca88 Date: Sun, 14 Feb 2021 19:21:34 +0100 Subject: [PATCH 2/2] Code review changes --- .../ResultOperatorProcessors/ProcessAny.cs | 9 +++++++-- .../ResultOperatorProcessors/ProcessContains.cs | 14 +------------- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessAny.cs b/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessAny.cs index 8712418f94a..0fcda0a5ef0 100644 --- a/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessAny.cs +++ b/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessAny.cs @@ -10,6 +10,11 @@ namespace NHibernate.Linq.Visitors.ResultOperatorProcessors public class ProcessAny : IResultOperatorProcessor { public void Process(AnyResultOperator anyOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree) + { + Process(tree); + } + + internal static void Process(IntermediateHqlTree tree) { if (tree.IsRoot) { @@ -24,8 +29,8 @@ public void Process(AnyResultOperator anyOperator, QueryModelVisitor queryModelV } else { - tree.SetRoot(tree.TreeBuilder.Exists((HqlQuery)tree.Root)); + tree.SetRoot(tree.TreeBuilder.Exists((HqlQuery) tree.Root)); } } } -} \ No newline at end of file +} diff --git a/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessContains.cs b/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessContains.cs index e8432cfa629..399025a3065 100644 --- a/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessContains.cs +++ b/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessContains.cs @@ -40,19 +40,7 @@ public void Process(ContainsResultOperator resultOperator, QueryModelVisitor que tree.AddWhereClause(tree.TreeBuilder.Equality( tree.TreeBuilder.Ident(GetFromAlias(tree.Root).AstNode.Text), itemExpression)); - if (tree.IsRoot) - { - tree.AddTakeClause(tree.TreeBuilder.Constant(1)); - Expression, bool>> x = l => l.Any(); - tree.AddListTransformer(x); - - Expression, bool>> px = l => l.Any(r => r); - tree.AddPostExecuteTransformer(px); - } - else - { - tree.SetRoot(tree.TreeBuilder.Exists((HqlQuery) tree.Root)); - } + ProcessAny.Process(tree); } else {