From a2aa6be4b34d11208321b3b3db6161441a128137 Mon Sep 17 00:00:00 2001 From: Alexey Kulakov Date: Mon, 24 May 2021 15:18:49 +0500 Subject: [PATCH 1/2] Raw api for being able to pass caching parameters from user --- .../Orm/Internals/CompiledQueryRunner.cs | 124 ++++++++-- Orm/Xtensive.Orm/Orm/QueryEndpoint.cs | 222 +++++++++++++++++- 2 files changed, 331 insertions(+), 15 deletions(-) diff --git a/Orm/Xtensive.Orm/Orm/Internals/CompiledQueryRunner.cs b/Orm/Xtensive.Orm/Orm/Internals/CompiledQueryRunner.cs index db3de3b23d..8cab291a60 100644 --- a/Orm/Xtensive.Orm/Orm/Internals/CompiledQueryRunner.cs +++ b/Orm/Xtensive.Orm/Orm/Internals/CompiledQueryRunner.cs @@ -1,4 +1,4 @@ -// Copyright (C) 2012-2020 Xtensive LLC. +// Copyright (C) 2012-2020 Xtensive LLC. // This code is distributed under MIT license terms. // See the License.txt file in the project root for more information. // Created by: Denis Krjuchkov @@ -7,6 +7,7 @@ using System; using System.Linq; using System.Linq.Expressions; +using System.Reflection; using System.Threading; using System.Threading.Tasks; using Xtensive.Core; @@ -47,7 +48,7 @@ public TResult ExecuteCompiled(Func query) return parameterizedQuery.ExecuteScalar(session, CreateParameterContext(parameterizedQuery)); } - GetScalarQuery(query, true, out var result); + _ = GetScalarQuery(query, true, out var result); return result; } @@ -155,16 +156,83 @@ private void AllocateParameterAndReplacer() } var closureType = queryTarget.GetType(); - var parameterType = WellKnownOrmTypes.ParameterOfT.MakeGenericType(closureType); - var valueMemberInfo = parameterType.GetProperty(nameof(Parameter.Value), closureType); - queryParameter = (Parameter) System.Activator.CreateInstance(parameterType, "pClosure"); - queryParameterReplacer = new ExtendedExpressionReplacer(expression => { + Type parameterType; + Type parameterValueType; + PropertyInfo valueMemberInfo; + if (queryParameter == null) { + parameterType = WellKnownOrmTypes.ParameterOfT.MakeGenericType(closureType); + parameterValueType = closureType; + queryParameter = (Parameter) System.Activator.CreateInstance(parameterType, "pClosure"); + valueMemberInfo = parameterType.GetProperty(nameof(Parameter.Value), closureType); + queryParameterReplacer = new ExtendedExpressionReplacer(RegularReplacer); + } + else { + parameterType = queryParameter.GetType(); + parameterValueType = queryParameter.GetType().GetGenericArguments()[0]; + valueMemberInfo = parameterType.GetProperty(nameof(Parameter.Value), parameterValueType); + queryParameterReplacer = new ExtendedExpressionReplacer(UserParameterReplacer); + } + + Expression RegularReplacer(Expression expression) + { if (expression.NodeType != ExpressionType.Constant) { return null; } + if (expression.Type.IsClosure()) { + if (expression.Type == closureType) { + return Expression.MakeMemberAccess(Expression.Constant(queryParameter, parameterType), valueMemberInfo); + } + throw new NotSupportedException(string.Format( + Strings.ExExpressionDefinedOutsideOfCachingQueryClosure, expression)); + } + + if (closureType.DeclaringType == null) { + if (expression.Type == closureType) { + // declaring type = null means that type is not nested + // and type = closure type means that it is declared instance property/field + // and query is executed from method of this instance + return Expression.MakeMemberAccess(Expression.Constant(queryParameter, parameterType), valueMemberInfo); + } + } + else { + // closure type is nested type + if (expression.Type == closureType) { + //nested class members + return Expression.MakeMemberAccess(Expression.Constant(queryParameter, parameterType), valueMemberInfo); + } + + if (expression.Type == closureType.DeclaringType) { + //access to instance field or property from funcs that runs execute within, see IssueJira0546 test for that case + var memberInfo = closureType.TryGetFieldInfoFromClosure(expression.Type); + if (memberInfo != null) { + return Expression.MakeMemberAccess( + Expression.MakeMemberAccess(Expression.Constant(queryParameter, parameterType), valueMemberInfo), + memberInfo); + } + } + + } + return null; + } + + Expression UserParameterReplacer(Expression expression) + { + if (expression.NodeType == ExpressionType.MemberAccess) { + if (expression.Type == parameterValueType) { + var memberExpression = expression as MemberExpression; + if (memberExpression.Expression == null) { + return null; + } + return Expression.MakeMemberAccess(Expression.Constant(queryParameter, parameterType), valueMemberInfo); + } + } + + if (expression.NodeType != ExpressionType.Constant) { + return null; + } if (expression.Type.IsClosure()) { - if (expression.Type==closureType) { + if (expression.Type == closureType) { return Expression.MakeMemberAccess(Expression.Constant(queryParameter, parameterType), valueMemberInfo); } @@ -172,19 +240,19 @@ private void AllocateParameterAndReplacer() Strings.ExExpressionDefinedOutsideOfCachingQueryClosure, expression)); } - if (closureType.DeclaringType==null) { - if (expression.Type==closureType) { + if (closureType.DeclaringType == null) { + if (expression.Type == closureType) { return Expression.MakeMemberAccess(Expression.Constant(queryParameter, parameterType), valueMemberInfo); } } else { - if (expression.Type==closureType) { + if (expression.Type == closureType) { return Expression.MakeMemberAccess(Expression.Constant(queryParameter, parameterType), valueMemberInfo); } - if (expression.Type==closureType.DeclaringType) { + if (expression.Type == closureType.DeclaringType) { var memberInfo = closureType.TryGetFieldInfoFromClosure(expression.Type); - if (memberInfo!=null) { + if (memberInfo != null) { return Expression.MakeMemberAccess( Expression.MakeMemberAccess(Expression.Constant(queryParameter, parameterType), valueMemberInfo), memberInfo); @@ -193,7 +261,7 @@ private void AllocateParameterAndReplacer() } return null; - }); + } } private ParameterizedQuery GetCachedQuery() @@ -236,5 +304,33 @@ public CompiledQueryRunner(QueryEndpoint endpoint, object queryKey, object query this.queryTarget = queryTarget; this.outerContext = outerContext; } + + private struct ParametersWrapper + { + public object RootTarget { get; private set; } + + public object UserClosure1 { get; set; } + public object UserClosure2 { get; set; } + + public object UserClosure3 { get; set; } + + public System.Collections.Generic.IDictionary TypeToInstanseMap { get; private set; } + + public ParametersWrapper(object rootTarger) + { + RootTarget = rootTarger; + UserClosure1 = null; + UserClosure2 = null; + UserClosure3 = null; + + TypeToInstanseMap = new System.Collections.Generic.Dictionary(); + } + } + + public CompiledQueryRunner(QueryEndpoint endpoint, object queryKey, object queryTarget, ParameterContext outerContext, Parameter userParameter) + : this(endpoint, queryKey, queryTarget, outerContext) + { + queryParameter = userParameter; + } } -} +} \ No newline at end of file diff --git a/Orm/Xtensive.Orm/Orm/QueryEndpoint.cs b/Orm/Xtensive.Orm/Orm/QueryEndpoint.cs index 9453b35328..cd06430281 100644 --- a/Orm/Xtensive.Orm/Orm/QueryEndpoint.cs +++ b/Orm/Xtensive.Orm/Orm/QueryEndpoint.cs @@ -449,6 +449,27 @@ public QueryResult Execute(object key, Func + /// Finds compiled query in cache by provided + /// and executes them if it's already cached; + /// otherwise executes the delegate + /// and caches the result. + /// + /// The type of the resulting sequence element. + /// Type of parameter container. + /// An object identifying this query in cache. + /// A delegate performing the query to cache. + /// An oblect that contains all parameters for caching. + /// Query result. + public QueryResult Execute(object key, Func> query, TParameterContainer parameterContainer) + where TParameterContainer : class + { + var parameterContext = new ParameterContext(); + var userParameter = CreateUserParameter(); + parameterContext.SetValue(userParameter, parameterContainer); + return new CompiledQueryRunner(this, key, parameterContainer, parameterContext, userParameter).ExecuteCompiled(query); + } + /// /// Finds compiled query in cache by provided delegate /// (in fact, by its instance) @@ -479,6 +500,27 @@ public QueryResult Execute(object key, Func + /// Finds compiled query in cache by provided + /// and executes them if it's already cached; + /// otherwise executes the delegate + /// and caches the result. + /// + /// The type of the resulting sequence element. + /// Type of parameter container. + /// An object identifying this query in cache. + /// A delegate performing the query to cache. + /// An oblect that contains all parameters for caching. + /// Query result. + public QueryResult Execute(object key, Func> query, TParameterContainer parameterContainer) + where TParameterContainer : class + { + var parameterContext = new ParameterContext(); + var userParameter = CreateUserParameter(); + parameterContext.SetValue(userParameter, parameterContainer); + return new CompiledQueryRunner(this, key, parameterContainer, parameterContext, userParameter).ExecuteCompiled(query); + } + /// /// Finds compiled query in cache by provided delegate /// (in fact, by its instance) @@ -509,6 +551,27 @@ public TResult Execute(object key, Func query) return new CompiledQueryRunner(this, key, query.Target).ExecuteCompiled(query); } + /// + /// Finds compiled query in cache by provided + /// and executes them if it's already cached; + /// otherwise executes the delegate + /// and caches the result. + /// + /// The type of the result. + /// Type of parameter container. + /// An object identifying this query in cache. + /// A delegate performing the query to cache. + /// An oblect that contains all parameters for caching. + /// Query result. + public TResult Execute(object key, Func query, TParameterContainer parameterContainer) + where TParameterContainer : class + { + var parameterContext = new ParameterContext(); + var userParameter = CreateUserParameter(); + parameterContext.SetValue(userParameter, parameterContainer); + return new CompiledQueryRunner(this, key, parameterContainer, parameterContext, userParameter).ExecuteCompiled(query); + } + /// /// Finds compiled query in cache by provided /// and executes them if it's already cached; @@ -521,7 +584,7 @@ public TResult Execute(object key, Func query) /// instance holding explicitly set /// values of query parameters. /// Query result. - public TResult Execute(object key, Func query, ParameterContext parameterContext) + internal TResult Execute(object key, Func query, ParameterContext parameterContext) { return new CompiledQueryRunner(this, key, query.Target, parameterContext).ExecuteCompiled(query); } @@ -592,6 +655,58 @@ public Task> ExecuteAsync(object key, Func> ExecuteAsync(object key, Func> query, CancellationToken token) => new CompiledQueryRunner(this, key, query.Target).ExecuteCompiledAsync(query, token); + /// + /// Finds compiled query in cache by provided + /// and asynchronously executes them if it's already cached; + /// otherwise asynchronously executes the delegate + /// and caches the result. + /// + /// Multiple active operations in the same session instance are not supported. Use + /// to ensure that all asynchronous operations have completed before calling + /// another method in this session. + /// The type of the resulting sequence element. + /// Type of parameter container. + /// An object identifying this query in cache. + /// A delegate performing the query to cache. + /// An oblect that contains all parameters for caching. + /// Task performing operation. + public Task> ExecuteAsync( + object key, Func> query, TParameterContainer parameterContainer) + where TParameterContainer : class + { + return ExecuteAsync(key, query, parameterContainer, CancellationToken.None); + } + + /// + /// Finds compiled query in cache by provided + /// and asynchronously executes them if it's already cached; + /// otherwise asynchronously executes the delegate + /// and caches the result. + /// + /// Multiple active operations in the same session instance are not supported. Use + /// to ensure that all asynchronous operations have completed before calling + /// another method in this session. + /// The type of the resulting sequence element. + /// Type of parameter container. + /// An object identifying this query in cache. + /// A delegate performing the query to cache. + /// An oblect that contains all parameters for caching. + /// Token to cancel operation. + /// Task performing operation. + public Task> ExecuteAsync( + object key, + Func> query, + TParameterContainer parameterContainer, + CancellationToken token) + where TParameterContainer : class + { + var parameterContext = new ParameterContext(); + var userParameter = CreateUserParameter(); + parameterContext.SetValue(userParameter, parameterContainer); + return new CompiledQueryRunner(this, key, parameterContainer, parameterContext, userParameter).ExecuteCompiledAsync(query, token); + } + + /// /// Finds compiled query in cache by provided delegate /// (in fact, by its instance) @@ -658,6 +773,55 @@ public Task> ExecuteAsync(object key, Func> ExecuteAsync(object key, Func> query, CancellationToken token) => new CompiledQueryRunner(this, key, query.Target).ExecuteCompiledAsync(query, token); + /// + /// Finds compiled query in cache by provided + /// and asynchronously executes them if it's already cached; + /// otherwise asynchronously executes the delegate + /// and caches the result. + /// + /// Multiple active operations in the same session instance are not supported. Use + /// to ensure that all asynchronous operations have completed before calling + /// another method in this session. + /// The type of the resulting sequence element. + /// Type of parameter container. + /// An object identifying this query in cache. + /// A delegate performing the query to cache. + /// An oblect that contains all parameters for caching. + /// Task performing operation. + public Task> ExecuteAsync( + object key, Func> query, TParameterContainer parameterContainer) + where TParameterContainer : class + { + return ExecuteAsync(key, query, parameterContainer, CancellationToken.None); + } + + /// + /// Finds compiled query in cache by provided + /// and asynchronously executes them if it's already cached; + /// otherwise asynchronously executes the delegate + /// and caches the result. + /// + /// Multiple active operations in the same session instance are not supported. Use + /// to ensure that all asynchronous operations have completed before calling + /// another method in this session. + /// The type of the resulting sequence element. + /// Type of parameter container. + /// An object identifying this query in cache. + /// A delegate performing the query to cache. + /// An oblect that contains all parameters for caching. + /// Token to cancel operation. + /// Task performing operation. + public Task> ExecuteAsync( + object key, Func> query, TParameterContainer parameterContainer, + CancellationToken token) + where TParameterContainer : class + { + var parameterContext = new ParameterContext(); + var userParameter = CreateUserParameter(); + parameterContext.SetValue(userParameter, parameterContainer); + return new CompiledQueryRunner(this, key, parameterContainer, parameterContext, userParameter).ExecuteCompiledAsync(query, token); + } + /// /// Finds compiled query in cache by provided delegate /// (in fact, by its instance) @@ -724,6 +888,55 @@ public Task ExecuteAsync(object key, Func ExecuteAsync(object key, Func query, CancellationToken token) => new CompiledQueryRunner(this, key, query.Target).ExecuteCompiledAsync(query, token); + /// + /// Finds compiled query in cache by provided + /// and asynchronously executes them if it's already cached; + /// otherwise asynchronously executes the delegate + /// and caches the result. + /// + /// Multiple active operations in the same session instance are not supported. Use + /// to ensure that all asynchronous operations have completed before calling + /// another method in this session. + /// The type of the result. + /// Type of parameter container. + /// An object identifying this query in cache. + /// A delegate performing the query to cache. + /// An oblect that contains all parameters for caching. + /// Task performing operation. + public Task ExecuteAsync( + object key, Func query, TParameterContainer parameterContainer) + where TParameterContainer : class + { + return ExecuteAsync(key, query, parameterContainer, CancellationToken.None); + } + + /// + /// Finds compiled query in cache by provided + /// and asynchronously executes them if it's already cached; + /// otherwise asynchronously executes the delegate + /// and caches the result. + /// + /// Multiple active operations in the same session instance are not supported. Use + /// to ensure that all asynchronous operations have completed before calling + /// another method in this session. + /// The type of the result. + /// Type of parameter container. + /// An object identifying this query in cache. + /// A delegate performing the query to cache. + /// An oblect that contains all parameters for caching. + /// Token to cancel operation. + /// Task performing operation. + public Task ExecuteAsync( + object key, Func query, TParameterContainer parameterContainer, + CancellationToken token) + where TParameterContainer : class + { + var parameterContext = new ParameterContext(); + var userParameter = CreateUserParameter(); + parameterContext.SetValue(userParameter, parameterContainer); + return new CompiledQueryRunner(this, key, parameterContainer, parameterContext, userParameter).ExecuteCompiledAsync(query, token); + } + #endregion #region Delayed Queries @@ -941,6 +1154,13 @@ private Expression BuildRootExpression(Type elementType) : Expression.Call(null, WellKnownMembers.Query.All.MakeGenericMethod(elementType)); } + private Parameter CreateUserParameter() + { + var parameterType = WellKnownOrmTypes.ParameterOfT.MakeGenericType(typeof(TParameterContainer)); + var userParameter = (Parameter) System.Activator.CreateInstance(parameterType, "uClosure"); + return userParameter; + } + #endregion From 61ddebf3cba733b609cf8aee9628b98dd1820628 Mon Sep 17 00:00:00 2001 From: Alexey Kulakov Date: Fri, 11 Jun 2021 19:46:27 +0500 Subject: [PATCH 2/2] Tests for new API method (only sync for now) --- .../InlineQueriesCachingTest.cs | 323 ++++ .../TestRunners.InstanceFieldTestRunner.cs | 731 +++++++++ .../TestRunners.InstancePropertyTestRunner.cs | 750 +++++++++ .../TestRunners.LocalVariableTestRunner.cs | 595 +++++++ .../TestRunners.NestedClassTestRunner.cs | 1378 +++++++++++++++++ .../TestRunners.ParameterTestRunner.cs | 640 ++++++++ .../TestRunners.StaticFieldTestRunner.cs | 731 +++++++++ .../TestRunners.StaticPropertyTestRunner.cs | 739 +++++++++ .../TestRunners.cs | 41 + 9 files changed, 5928 insertions(+) create mode 100644 Orm/Xtensive.Orm.Tests/Storage/CustomClosureForCachingQueries/InlineQueriesCachingTest.cs create mode 100644 Orm/Xtensive.Orm.Tests/Storage/CustomClosureForCachingQueries/TestRunners.InstanceFieldTestRunner.cs create mode 100644 Orm/Xtensive.Orm.Tests/Storage/CustomClosureForCachingQueries/TestRunners.InstancePropertyTestRunner.cs create mode 100644 Orm/Xtensive.Orm.Tests/Storage/CustomClosureForCachingQueries/TestRunners.LocalVariableTestRunner.cs create mode 100644 Orm/Xtensive.Orm.Tests/Storage/CustomClosureForCachingQueries/TestRunners.NestedClassTestRunner.cs create mode 100644 Orm/Xtensive.Orm.Tests/Storage/CustomClosureForCachingQueries/TestRunners.ParameterTestRunner.cs create mode 100644 Orm/Xtensive.Orm.Tests/Storage/CustomClosureForCachingQueries/TestRunners.StaticFieldTestRunner.cs create mode 100644 Orm/Xtensive.Orm.Tests/Storage/CustomClosureForCachingQueries/TestRunners.StaticPropertyTestRunner.cs create mode 100644 Orm/Xtensive.Orm.Tests/Storage/CustomClosureForCachingQueries/TestRunners.cs diff --git a/Orm/Xtensive.Orm.Tests/Storage/CustomClosureForCachingQueries/InlineQueriesCachingTest.cs b/Orm/Xtensive.Orm.Tests/Storage/CustomClosureForCachingQueries/InlineQueriesCachingTest.cs new file mode 100644 index 0000000000..9dae444532 --- /dev/null +++ b/Orm/Xtensive.Orm.Tests/Storage/CustomClosureForCachingQueries/InlineQueriesCachingTest.cs @@ -0,0 +1,323 @@ +using System; +using System.Collections.Generic; +using System.Dynamic; +using System.Linq; +using System.Text; +using NUnit.Framework; +using Xtensive.Core; +using Xtensive.Orm; +using Xtensive.Orm.Configuration; +using Xtensive.Orm.Tests.Storage.InlineQueriesCachingTestModel; +using Xtensive.Orm.Tests.Storage.InlineQueriesCachingTestModel.TestRunners; + +namespace Xtensive.Orm.Tests.Storage.InlineQueriesCachingTestModel +{ + [HierarchyRoot] + public class Enterprise : Entity + { + [Field, Key] + public int Id { get; private set; } + + [Field] + public string Name { get; set; } + + [Field] + public DateTime CreationDate { get; set; } + } + + public class BaseParameterContainer + { + public string BaseNameField; + + public string BaseNameProp { get; set; } + } + + public class ParameterContainer : BaseParameterContainer + { + public string NameField; + + public string NameProp { get; set; } + } +} + +namespace Xtensive.Orm.Tests.Storage +{ + public class InlineQueriesCachingTest : AutoBuildTest + { + protected override DomainConfiguration BuildConfiguration() + { + var config = base.BuildConfiguration(); + config.Types.Register(typeof(Enterprise).Assembly, typeof(Enterprise).Namespace); + config.UpgradeMode = DomainUpgradeMode.Recreate; + return config; + } + + protected override void PopulateData() + { + var testNames = GetTestNames(); + + using (var session = Domain.OpenSession()) + using (var tx = session.OpenTransaction()) { + foreach (var name in testNames) { + _ = new Enterprise() { Name = name }; + } + tx.Complete(); + } + } + + [Test] + public void LocalVariableTest() + { + using (var session = Domain.OpenSession()) + using (var tx = session.OpenTransaction()) { + var tester = new LocalVariableTestRunner(); + tester.GeneralAccessScalar(session); + tester.GeneralAccessSequence(session); + tester.GeneralAccessOrderedSequence(session); + + tester.AccessFromNestedMethodScalar(session); + tester.AccessFromNestedMethodSequence(session); + tester.AccessFromNestedMethodOrderedSequence(session); + + tester.AccessFromLocalFuncScalar(session); + tester.AccessFromLocalFuncSequence(session); + tester.AccessFromLocalFuncOrderedSequence(session); + } + } + + [Test] + public void ParameterTest() + { + using (var session = Domain.OpenSession()) + using (var tx = session.OpenTransaction()) { + var tester = new ParameterTestRunner(); + tester.GeneralAccessScalar(session); + tester.GeneralAccessSequence(session); + tester.GeneralAccessOrderedSequence(session); + + tester.AccessFromNestedMethodScalar(session); + tester.AccessFromNestedMethodSequence(session); + tester.AccessFromNestedMethodOrderedSequence(session); + + tester.AccessFromLocalFuncScalar(session); + tester.AccessFromLocalFuncSequence(session); + tester.AccessFromLocalFuncOrderedSequence(session); + } + } + + [Test] + public void StaticFieldTest() + { + using (var session = Domain.OpenSession()) + using (var tx = session.OpenTransaction()) { + var tester = new StaticFieldTestRunner(); + tester.GeneralAccessScalar(session); + tester.GeneralAccessSequence(session); + tester.GeneralAccessOrderedSequence(session); + + tester.AccessFromNestedMethodScalar(session); + tester.AccessFromNestedMethodSequence(session); + tester.AccessFromNestedMethodOrderedSequence(session); + + tester.AccessFromLocalFuncScalar(session); + tester.AccessFromLocalFuncSequence(session); + tester.AccessFromLocalFuncOrderedSequence(session); + } + } + + [Test] + public void StaticPropertyTest() + { + using (var session = Domain.OpenSession()) + using (var tx = session.OpenTransaction()) { + var tester = new StaticPropertyTestRunner(); + tester.GeneralAccessScalar(session); + tester.GeneralAccessSequence(session); + tester.GeneralAccessOrderedSequence(session); + + tester.AccessFromNestedMethodScalar(session); + tester.AccessFromNestedMethodSequence(session); + tester.AccessFromNestedMethodOrderedSequence(session); + + tester.AccessFromLocalFuncScalar(session); + tester.AccessFromLocalFuncSequence(session); + tester.AccessFromLocalFuncOrderedSequence(session); + } + } + + [Test] + public void InstanceFieldTest() + { + using (var session = Domain.OpenSession()) + using (var tx = session.OpenTransaction()) { + var tester = new InstanceFieldTestRunner(); + tester.GeneralAccessScalar(session); + tester.GeneralAccessSequence(session); + tester.GeneralAccessOrderedSequence(session); + + tester.AccessFromNestedMethodScalar(session); + tester.AccessFromNestedMethodSequence(session); + tester.AccessFromNestedMethodOrderedSequence(session); + + tester.AccessFromLocalFuncScalar(session); + tester.AccessFromLocalFuncSequence(session); + tester.AccessFromLocalFuncOrderedSequence(session); + } + } + + [Test] + public void InstancePropertyTest() + { + using (var session = Domain.OpenSession()) + using (var tx = session.OpenTransaction()) { + var tester = new InstancePropertyTestRunner(); + tester.GeneralAccessScalar(session); + tester.GeneralAccessSequence(session); + tester.GeneralAccessOrderedSequence(session); + + tester.AccessFromNestedMethodScalar(session); + tester.AccessFromNestedMethodSequence(session); + tester.AccessFromNestedMethodOrderedSequence(session); + + tester.AccessFromLocalFuncScalar(session); + tester.AccessFromLocalFuncSequence(session); + tester.AccessFromLocalFuncOrderedSequence(session); + } + } + + [Test] + public void NestedClassTest() + { + using (var session = Domain.OpenSession()) + using (var tx = session.OpenTransaction()) { + var tester = new NestedClassTestRunner(); + tester.AccessInsideNestedClassTest(session); + tester.AccessOutideNestedClassTest(session); + } + } + + private IEnumerable GetTestNames() + { + var classNames = new string[] { + nameof(LocalVariableTestRunner), + nameof(ParameterTestRunner), + nameof(StaticFieldTestRunner), + nameof(StaticPropertyTestRunner), + nameof(InstanceFieldTestRunner), + nameof(InstancePropertyTestRunner) + }; + var tests = new string[] { + nameof(StaticFieldTestRunner.GeneralAccessScalar), + nameof(StaticFieldTestRunner.GeneralAccessSequence), + nameof(StaticFieldTestRunner.GeneralAccessOrderedSequence), + nameof(StaticFieldTestRunner.AccessFromNestedMethodScalar), + nameof(StaticFieldTestRunner.AccessFromNestedMethodSequence), + nameof(StaticFieldTestRunner.AccessFromNestedMethodOrderedSequence), + nameof(StaticFieldTestRunner.AccessFromLocalFuncScalar), + nameof(StaticFieldTestRunner.AccessFromLocalFuncSequence), + nameof(StaticFieldTestRunner.AccessFromLocalFuncOrderedSequence), + nameof(StaticFieldTestRunner.CacheAcrossMethodsScalar), + nameof(StaticFieldTestRunner.CacheAcrossMethodsSequence), + nameof(StaticFieldTestRunner.CacheAcrossMethodsOrderedSequence) + }; + + foreach (var className1 in classNames) { + foreach (var methodName in tests) { + yield return className1 + methodName + "BaseField1"; + yield return className1 + methodName + "BaseProp1"; + yield return className1 + methodName + "Field1"; + yield return className1 + methodName + "Prop1"; + yield return className1 + methodName + "BaseField2"; + yield return className1 + methodName + "BaseProp2"; + yield return className1 + methodName + "Field2"; + yield return className1 + methodName + "Prop2"; + yield return className1 + methodName + "BaseField3"; + yield return className1 + methodName + "BaseProp3"; + yield return className1 + methodName + "Field3"; + yield return className1 + methodName + "Prop3"; + } + } + + var className2 = nameof(NestedClassTestRunner); + tests = new string[] { + nameof(NestedClassTestRunner.AccessInsideNestedClassTest), + nameof(NestedClassTestRunner.AccessOutideNestedClassTest), + }; + + foreach (var methodName in tests) { + foreach (var index in Enumerable.Range(1, 8)) { + yield return className2 + methodName + "BaseField" + index; + yield return className2 + methodName + "BaseProp" + index; + yield return className2 + methodName + "Field" + index; + yield return className2 + methodName + "Prop" + index; + } + } + } + + + //private void TestBody(SomeType parameter) + //{ + // var localParameter = new SomeType() { Name = "localParameter" }; + + // using (var session = Domain.OpenSession()) + // using (var tx = session.OpenTransaction()) { + // var entsLocal = session.Query.All().Where(q => q.Name == localParameter.Name); + // var entsParameter = session.Query.All().Where(q => q.Name == parameter.Name); + // var entsstaticField = session.Query.All().Where(q => q.Name == staticField.Name); + // var entsStaticProperty = session.Query.All().Where(q => q.Name == StaticProperty.Name); + // var entsinstanceField = session.Query.All().Where(q => q.Name == instanceField.Name); + // var entsInstanceProperty = session.Query.All().Where(q => q.Name == InstanceProperty.Name); + + // //Assert.AreEqual(0, session.Query.Execute("the_key1", (q) => entsLocal.Count(), localParameter)); + // //Assert.AreEqual(0, session.Query.Execute("the_key1", (q) => entsLocal.Count(), parameter)); + // //Assert.AreEqual(0, session.Query.Execute("the_key1", (q) => entsLocal.Count(), staticField)); + // //Assert.AreEqual(0, session.Query.Execute("the_key1", (q) => entsLocal.Count(), StaticProperty)); + // //Assert.AreEqual(0, session.Query.Execute("the_key1", (q) => entsLocal.Count(), instanceField)); + // //Assert.AreEqual(0, session.Query.Execute("the_key1", (q) => entsLocal.Count(), InstanceProperty)); + + // //Assert.AreEqual(0, session.Query.Execute("the_key2", (q) => entsParameter.Count(), localParameter)); + // //Assert.AreEqual(0, session.Query.Execute("the_key2", (q) => entsParameter.Count(), parameter)); + // //Assert.AreEqual(0, session.Query.Execute("the_key2", (q) => entsParameter.Count(), staticField)); + // //Assert.AreEqual(0, session.Query.Execute("the_key2", (q) => entsParameter.Count(), StaticProperty)); + // //Assert.AreEqual(0, session.Query.Execute("the_key2", (q) => entsParameter.Count(), instanceField)); + // //Assert.AreEqual(0, session.Query.Execute("the_key2", (q) => entsParameter.Count(), InstanceProperty)); + + // //Assert.AreEqual(0, session.Query.Execute("the_key5", (q) => entsinstanceField.Count(), localParameter)); + // //Assert.AreEqual(0, session.Query.Execute("the_key5", (q) => entsinstanceField.Count(), parameter)); + // //Assert.AreEqual(0, session.Query.Execute("the_key5", (q) => entsinstanceField.Count(), staticField)); + // //Assert.AreEqual(0, session.Query.Execute("the_key5", (q) => entsinstanceField.Count(), StaticProperty)); + // //Assert.AreEqual(0, session.Query.Execute("the_key5", (q) => entsinstanceField.Count(), instanceField)); + // //Assert.AreEqual(0, session.Query.Execute("the_key5", (q) => entsinstanceField.Count(), InstanceProperty)); + + // //Assert.AreEqual(0, session.Query.Execute("the_key6", (q) => entsInstanceProperty.Count(), localParameter)); + // //Assert.AreEqual(0, session.Query.Execute("the_key6", (q) => entsInstanceProperty.Count(), parameter)); + // //Assert.AreEqual(0, session.Query.Execute("the_key6", (q) => entsInstanceProperty.Count(), staticField)); + // //Assert.AreEqual(0, session.Query.Execute("the_key6", (q) => entsInstanceProperty.Count(), StaticProperty)); + // //Assert.AreEqual(0, session.Query.Execute("the_key6", (q) => entsInstanceProperty.Count(), instanceField)); + // //Assert.AreEqual(0, session.Query.Execute("the_key6", (q) => entsInstanceProperty.Count(), InstanceProperty)); + + + // Assert.AreEqual(0, session.Query.Execute("the_key3", (q) => entsstaticField.Count(), localParameter)); + // //Assert.AreEqual(0, session.Query.Execute("the_key3", (q) => q.All().Where(q => q.Name == staticField.Name).Count())); + // //Assert.AreEqual(0, session.Query.Execute("the_key3", (q) => q.All().Where(q => q.Name == staticField.Name).Count())); + // //Assert.AreEqual(0, session.Query.Execute("the_key3", (q) => entsstaticField.Count(), parameter)); + // //Assert.AreEqual(0, session.Query.Execute("the_key3", (q) => entsstaticField.Count(), staticField)); + // //Assert.AreEqual(0, session.Query.Execute("the_key3", (q) => entsstaticField.Count(), StaticProperty)); + // //Assert.AreEqual(0, session.Query.Execute("the_key3", (q) => entsstaticField.Count(), instanceField)); + // //Assert.AreEqual(0, session.Query.Execute("the_key3", (q) => entsstaticField.Count(), InstanceProperty)); + + // //Assert.AreEqual(0, session.Query.Execute("the_key4", (q) => entsStaticProperty.Count(), localParameter)); + // //Assert.AreEqual(0, session.Query.Execute("the_key4", (q) => entsStaticProperty.Count(), parameter)); + // //Assert.AreEqual(0, session.Query.Execute("the_key4", (q) => entsStaticProperty.Count(), staticField)); + // //Assert.AreEqual(0, session.Query.Execute("the_key4", (q) => entsStaticProperty.Count(), StaticProperty)); + // //Assert.AreEqual(0, session.Query.Execute("the_key4", (q) => entsStaticProperty.Count(), instanceField)); + // //Assert.AreEqual(0, session.Query.Execute("the_key4", (q) => entsStaticProperty.Count(), InstanceProperty)); + + // //Assert.AreEqual(0, session.Query.Execute("the_key", (q) => ents.Count(), someType2)); + // //Assert.AreEqual(0, session.Query.Execute("the_key", (q) => ents.Count(), someType3)); + // //Assert.AreEqual(0, session.Query.Execute("the_key", (q) => ents.Count(), someType4)); + // //Assert.AreEqual(0, session.Query.Execute("the_key", (q) => ents.Count(), someType5)); + // } + //} + } +} diff --git a/Orm/Xtensive.Orm.Tests/Storage/CustomClosureForCachingQueries/TestRunners.InstanceFieldTestRunner.cs b/Orm/Xtensive.Orm.Tests/Storage/CustomClosureForCachingQueries/TestRunners.InstanceFieldTestRunner.cs new file mode 100644 index 0000000000..0c9cde9229 --- /dev/null +++ b/Orm/Xtensive.Orm.Tests/Storage/CustomClosureForCachingQueries/TestRunners.InstanceFieldTestRunner.cs @@ -0,0 +1,731 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NUnit.Framework; +using Xtensive.Orm.Tests.Storage.InlineQueriesCachingTestModel; + +namespace Xtensive.Orm.Tests.Storage.InlineQueriesCachingTestModel.TestRunners +{ + public class InstanceFieldTestRunner : TestRunnerBase + { + private readonly static string thisClassName = nameof(InstanceFieldTestRunner); + + private ParameterContainer field1; + private ParameterContainer field2; + private ParameterContainer field3; + + protected override string ThisClassName => thisClassName; + + public void GeneralAccessScalar(Session session) + { + var thisMethodName = nameof(InstanceFieldTestRunner.GeneralAccessScalar); + + InitVariables(thisMethodName, out field1, out field2, out field3); + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == field1.NameField); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "Field"); + + var result = session.Query.Execute(cachingKey, (q) => query.Count(), field1); + Assert.That(result, Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.Count(), field2); + Assert.That(result, Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.Count(), field3); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.NameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "Prop"); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), field1); + Assert.That(result, Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.Count(), field2); + Assert.That(result, Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.Count(), field3); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseField"); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), field1); + Assert.That(result, Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.Count(), field2); + Assert.That(result, Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.Count(), field3); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), field1); + Assert.That(result, Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.Count(), field2); + Assert.That(result, Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.Count(), field3); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + public void GeneralAccessSequence(Session session) + { + var thisMethodName = nameof(InstanceFieldTestRunner.GeneralAccessSequence); + + InitVariables(thisMethodName, out field1, out field2, out field3); + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == field1.NameField); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "Field"); + + var result = session.Query.Execute(cachingKey, (q) => query, field1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query, field2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query, field3); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.NameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "Prop"); + + result = session.Query.Execute(cachingKey, (q) => query, field1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query, field2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query, field3); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseField"); + + result = session.Query.Execute(cachingKey, (q) => query, field1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query, field2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query, field3); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + result = session.Query.Execute(cachingKey, (q) => query, field1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query, field2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query, field3); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + public void GeneralAccessOrderedSequence(Session session) + { + var thisMethodName = nameof(InstanceFieldTestRunner.GeneralAccessOrderedSequence); + + InitVariables(thisMethodName, out field1, out field2, out field3); + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == field1.NameField); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "Field"); + + var result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), field1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), field2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), field3); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.NameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "Prop"); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), field1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), field2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), field3); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseField"); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), field1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), field2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), field3); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), field1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), field2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), field3); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + public void AccessFromNestedMethodScalar(Session session) + { + var thisMethodName = nameof(InstanceFieldTestRunner.AccessFromNestedMethodScalar); + + InitVariables(thisMethodName, out field1, out field2, out field3); + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == field1.NameField); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "Field"); + + var result = Execute1(); + Assert.That(result, Is.EqualTo(1)); + result = Execute2(); + Assert.That(result, Is.EqualTo(1)); + result = Execute3(); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.NameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "Prop"); + + result = Execute1(); + Assert.That(result, Is.EqualTo(1)); + result = Execute2(); + Assert.That(result, Is.EqualTo(1)); + result = Execute3(); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseField"); + + result = Execute1(); + Assert.That(result, Is.EqualTo(1)); + result = Execute2(); + Assert.That(result, Is.EqualTo(1)); + result = Execute3(); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + result = Execute1(); + Assert.That(result, Is.EqualTo(1)); + result = Execute2(); + Assert.That(result, Is.EqualTo(1)); + result = Execute3(); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + + int Execute1() + { + return session.Query.Execute(cachingKey, (q) => query.Count(), field1); + } + int Execute2() + { + return session.Query.Execute(cachingKey, (q) => query.Count(), field2); + } + int Execute3() + { + return session.Query.Execute(cachingKey, (q) => query.Count(), field3); + } + } + + public void AccessFromNestedMethodSequence(Session session) + { + var thisMethodName = nameof(InstanceFieldTestRunner.AccessFromNestedMethodSequence); + + InitVariables(thisMethodName, out field1, out field2, out field3); + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == field1.NameField); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "Field"); + + var result = Execute1(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute2(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute3(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.NameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "Prop"); + + result = Execute1(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute2(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute3(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseField"); + + result = Execute1(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute2(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute3(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + result = Execute1(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute2(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute3(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + + IEnumerable Execute1() + { + return session.Query.Execute(cachingKey, (q) => query, field1); + } + IEnumerable Execute2() + { + return session.Query.Execute(cachingKey, (q) => query, field2); + } + IEnumerable Execute3() + { + return session.Query.Execute(cachingKey, (q) => query, field3); + } + } + + public void AccessFromNestedMethodOrderedSequence(Session session) + { + var thisMethodName = nameof(InstanceFieldTestRunner.AccessFromNestedMethodOrderedSequence); + + InitVariables(thisMethodName, out field1, out field2, out field3); + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == field1.NameField); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "Field"); + + var result = Execute1(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute2(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute3(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.NameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "Prop"); + + result = Execute1(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute2(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute3(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseField"); + + result = Execute1(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute2(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute3(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + result = Execute1(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute2(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute3(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + + IEnumerable Execute1() + { + return session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), field1); + } + IEnumerable Execute2() + { + return session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), field2); + } + IEnumerable Execute3() + { + return session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), field3); + } + } + + public void AccessFromLocalFuncScalar(Session session) + { + var thisMethodName = nameof(InstanceFieldTestRunner.AccessFromLocalFuncScalar); + + InitVariables(thisMethodName, out field1, out field2, out field3); + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == field1.NameField); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "Field"); + +#pragma warning disable IDE0039 // Use local function + Func execute1 = () => session.Query.Execute(cachingKey, (q) => query.Count(), field1); + Func execute2 = () => session.Query.Execute(cachingKey, (q) => query.Count(), field2); + Func execute3 = () => session.Query.Execute(cachingKey, (q) => query.Count(), field3); +#pragma warning restore IDE0039 // Use local function + + var result = execute1.Invoke(); + Assert.That(result, Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result, Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.NameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "Prop"); + + result = execute1.Invoke(); + Assert.That(result, Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result, Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseField"); + + result = execute1.Invoke(); + Assert.That(result, Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result, Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + result = execute1.Invoke(); + Assert.That(result, Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result, Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + public void AccessFromLocalFuncSequence(Session session) + { + var thisMethodName = nameof(InstanceFieldTestRunner.AccessFromLocalFuncSequence); + + InitVariables(thisMethodName, out field1, out field2, out field3); + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == field1.NameField); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "Field"); + +#pragma warning disable IDE0039 // Use local function + Func> execute1 = () => session.Query.Execute(cachingKey, (q) => query, field1); + Func> execute2 = () => session.Query.Execute(cachingKey, (q) => query, field2); + Func> execute3 = () => session.Query.Execute(cachingKey, (q) => query, field3); +#pragma warning restore IDE0039 // Use local function + + var result = execute1.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result, Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.NameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "Prop"); + + result = execute1.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseField"); + + result = execute1.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + result = execute1.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + public void AccessFromLocalFuncOrderedSequence(Session session) + { + var thisMethodName = nameof(InstanceFieldTestRunner.AccessFromLocalFuncOrderedSequence); + + InitVariables(thisMethodName, out field1, out field2, out field3); + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == field1.NameField); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "Field"); + +#pragma warning disable IDE0039 // Use local function + Func> execute1 = () => session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), field1); + Func> execute2 = () => session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), field2); + Func> execute3 = () => session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), field3); +#pragma warning restore IDE0039 // Use local function + + var result = execute1.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.NameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "Prop"); + + result = execute1.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseField"); + + result = execute1.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + result = execute1.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + public void CacheAcrossMethodsScalar(Session session) + { + var thisMethodName = nameof(InstanceFieldTestRunner.CacheAcrossMethodsScalar); + + InitVariables(thisMethodName, out field1, out field2, out field3); + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var sharedQueryable = session.Query.All().Where(q => q.Name == field1.BaseNameProp); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + var result = ScalarMethod1(session, cachingKey, sharedQueryable); + Assert.That(result, Is.EqualTo(1)); + result = ScalarMethod2(session, cachingKey, sharedQueryable); + Assert.That(result, Is.EqualTo(1)); + result = ScalarMethod3(session, cachingKey, sharedQueryable); + Assert.That(result, Is.EqualTo(1)); + + var queryable1 = session.Query.All().Where(q => q.Name == field1.BaseNameProp); + var queryable2 = session.Query.All().Where(q => q.Name == field1.BaseNameProp); + var queryable3 = session.Query.All().Where(q => q.Name == field1.BaseNameProp); + + result = ScalarMethod1(session, cachingKey, queryable1); + Assert.That(result, Is.EqualTo(1)); + result = ScalarMethod1(session, cachingKey, queryable2); + Assert.That(result, Is.EqualTo(1)); + result = ScalarMethod1(session, cachingKey, queryable3); + Assert.That(result, Is.EqualTo(1)); + + result = ScalarMethod2(session, cachingKey, queryable1); + Assert.That(result, Is.EqualTo(1)); + result = ScalarMethod2(session, cachingKey, queryable2); + Assert.That(result, Is.EqualTo(1)); + result = ScalarMethod2(session, cachingKey, queryable3); + Assert.That(result, Is.EqualTo(1)); + + result = ScalarMethod3(session, cachingKey, queryable1); + Assert.That(result, Is.EqualTo(1)); + result = ScalarMethod3(session, cachingKey, queryable2); + Assert.That(result, Is.EqualTo(1)); + result = ScalarMethod3(session, cachingKey, queryable3); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + public void CacheAcrossMethodsSequence(Session session) + { + var thisMethodName = nameof(InstanceFieldTestRunner.CacheAcrossMethodsSequence); + + InitVariables(thisMethodName, out field1, out field2, out field3); + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var sharedQueryable = session.Query.All().Where(q => q.Name == field1.BaseNameProp); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + var result = SequenceMethod1(session, cachingKey, sharedQueryable); + Assert.That(result.Count(), Is.EqualTo(1)); + result = SequenceMethod2(session, cachingKey, sharedQueryable); + Assert.That(result.Count(), Is.EqualTo(1)); + result = SequenceMethod3(session, cachingKey, sharedQueryable); + Assert.That(result.Count(), Is.EqualTo(1)); + + var queryable1 = session.Query.All().Where(q => q.Name == field1.BaseNameProp); + var queryable2 = session.Query.All().Where(q => q.Name == field1.BaseNameProp); + var queryable3 = session.Query.All().Where(q => q.Name == field1.BaseNameProp); + + result = SequenceMethod1(session, cachingKey, queryable1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = SequenceMethod1(session, cachingKey, queryable2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = SequenceMethod1(session, cachingKey, queryable3); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = SequenceMethod2(session, cachingKey, queryable1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = SequenceMethod2(session, cachingKey, queryable2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = SequenceMethod2(session, cachingKey, queryable3); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = SequenceMethod3(session, cachingKey, queryable1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = SequenceMethod3(session, cachingKey, queryable2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = SequenceMethod3(session, cachingKey, queryable3); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + public void CacheAcrossMethodsOrderedSequence(Session session) + { + var thisMethodName = nameof(InstanceFieldTestRunner.CacheAcrossMethodsOrderedSequence); + + InitVariables(thisMethodName, out field1, out field2, out field3); + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var sharedQueryable = session.Query.All().Where(q => q.Name == field1.BaseNameProp); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + var result = OrderedSequenceMethod1(session, cachingKey, sharedQueryable); + Assert.That(result.Count(), Is.EqualTo(1)); + result = OrderedSequenceMethod2(session, cachingKey, sharedQueryable); + Assert.That(result.Count(), Is.EqualTo(1)); + result = OrderedSequenceMethod3(session, cachingKey, sharedQueryable); + Assert.That(result.Count(), Is.EqualTo(1)); + + var queryable1 = session.Query.All().Where(q => q.Name == field1.BaseNameProp); + var queryable2 = session.Query.All().Where(q => q.Name == field1.BaseNameProp); + var queryable3 = session.Query.All().Where(q => q.Name == field1.BaseNameProp); + + result = OrderedSequenceMethod1(session, cachingKey, queryable1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = OrderedSequenceMethod1(session, cachingKey, queryable2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = OrderedSequenceMethod1(session, cachingKey, queryable3); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = OrderedSequenceMethod2(session, cachingKey, queryable1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = OrderedSequenceMethod2(session, cachingKey, queryable2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = OrderedSequenceMethod2(session, cachingKey, queryable3); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = OrderedSequenceMethod3(session, cachingKey, queryable1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = OrderedSequenceMethod3(session, cachingKey, queryable2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = OrderedSequenceMethod3(session, cachingKey, queryable3); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + private int ScalarMethod1(Session session, string cachingKey, IQueryable query) => + session.Query.Execute(cachingKey, (q) => query.Count(), field1); + + private int ScalarMethod2(Session session, string cachingKey, IQueryable query) => + session.Query.Execute(cachingKey, (q) => query.Count(), field2); + + private int ScalarMethod3(Session session, string cachingKey, IQueryable query) => + session.Query.Execute(cachingKey, (q) => query.Count(), field3); + + private IEnumerable SequenceMethod1(Session session, string cachingKey, IQueryable query) => + session.Query.Execute(cachingKey, (q) => query, field1); + + private IEnumerable SequenceMethod2(Session session, string cachingKey, IQueryable query) => + session.Query.Execute(cachingKey, (q) => query, field2); + + private IEnumerable SequenceMethod3(Session session, string cachingKey, IQueryable query) => + session.Query.Execute(cachingKey, (q) => query, field3); + + private IEnumerable OrderedSequenceMethod1(Session session, string cachingKey, IQueryable query) => + session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), field1); + + private IEnumerable OrderedSequenceMethod2(Session session, string cachingKey, IQueryable query) => + session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), field2); + + private IEnumerable OrderedSequenceMethod3(Session session, string cachingKey, IQueryable query) => + session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), field3); + } +} diff --git a/Orm/Xtensive.Orm.Tests/Storage/CustomClosureForCachingQueries/TestRunners.InstancePropertyTestRunner.cs b/Orm/Xtensive.Orm.Tests/Storage/CustomClosureForCachingQueries/TestRunners.InstancePropertyTestRunner.cs new file mode 100644 index 0000000000..377711e0ed --- /dev/null +++ b/Orm/Xtensive.Orm.Tests/Storage/CustomClosureForCachingQueries/TestRunners.InstancePropertyTestRunner.cs @@ -0,0 +1,750 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NUnit.Framework; +using Xtensive.Orm.Tests.Storage.InlineQueriesCachingTestModel; + +namespace Xtensive.Orm.Tests.Storage.InlineQueriesCachingTestModel.TestRunners +{ + public class InstancePropertyTestRunner : TestRunnerBase + { + private readonly static string thisClassName = nameof(InstancePropertyTestRunner); + + private ParameterContainer Prop1 { get; set; } + private ParameterContainer Prop2 { get; set; } + private ParameterContainer Prop3 { get; set; } + + protected override string ThisClassName => thisClassName; + + public void GeneralAccessScalar(Session session) + { + var thisMethodName = nameof(InstancePropertyTestRunner.GeneralAccessScalar); + + InitProperties(thisMethodName); + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == Prop1.NameField); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "Field"); + + var result = session.Query.Execute(cachingKey, (q) => query.Count(), Prop1); + Assert.That(result, Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.Count(), Prop2); + Assert.That(result, Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.Count(), Prop3); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.NameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "Prop"); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), Prop1); + Assert.That(result, Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.Count(), Prop2); + Assert.That(result, Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.Count(), Prop3); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseField"); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), Prop1); + Assert.That(result, Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.Count(), Prop2); + Assert.That(result, Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.Count(), Prop3); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), Prop1); + Assert.That(result, Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.Count(), Prop2); + Assert.That(result, Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.Count(), Prop3); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + public void GeneralAccessSequence(Session session) + { + var thisMethodName = nameof(InstancePropertyTestRunner.GeneralAccessSequence); + + InitProperties(thisMethodName); + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == Prop1.NameField); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "Field"); + + var result = session.Query.Execute(cachingKey, (q) => query, Prop1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query, Prop2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query, Prop3); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.NameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "Prop"); + + result = session.Query.Execute(cachingKey, (q) => query, Prop1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query, Prop2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query, Prop3); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseField"); + + result = session.Query.Execute(cachingKey, (q) => query, Prop1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query, Prop2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query, Prop3); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + result = session.Query.Execute(cachingKey, (q) => query, Prop1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query, Prop2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query, Prop3); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + public void GeneralAccessOrderedSequence(Session session) + { + var thisMethodName = nameof(InstancePropertyTestRunner.GeneralAccessOrderedSequence); + + InitProperties(thisMethodName); + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == Prop1.NameField); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "Field"); + + var result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e=>e.Id), Prop1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), Prop2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), Prop3); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.NameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "Prop"); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), Prop1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), Prop2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), Prop3); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseField"); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), Prop1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), Prop2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), Prop3); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), Prop1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), Prop2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), Prop3); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + public void AccessFromNestedMethodScalar(Session session) + { + var thisMethodName = nameof(InstancePropertyTestRunner.AccessFromNestedMethodScalar); + + InitProperties(thisMethodName); + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == Prop1.NameField); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "Field"); + + var result = Execute1(); + Assert.That(result, Is.EqualTo(1)); + result = Execute2(); + Assert.That(result, Is.EqualTo(1)); + result = Execute3(); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.NameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "Prop"); + + result = Execute1(); + Assert.That(result, Is.EqualTo(1)); + result = Execute2(); + Assert.That(result, Is.EqualTo(1)); + result = Execute3(); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseField"); + + result = Execute1(); + Assert.That(result, Is.EqualTo(1)); + result = Execute2(); + Assert.That(result, Is.EqualTo(1)); + result = Execute3(); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + result = Execute1(); + Assert.That(result, Is.EqualTo(1)); + result = Execute2(); + Assert.That(result, Is.EqualTo(1)); + result = Execute3(); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + + int Execute1() + { + return session.Query.Execute(cachingKey, (q) => query.Count(), Prop1); + } + int Execute2() + { + return session.Query.Execute(cachingKey, (q) => query.Count(), Prop2); + } + int Execute3() + { + return session.Query.Execute(cachingKey, (q) => query.Count(), Prop3); + } + } + + public void AccessFromNestedMethodSequence(Session session) + { + var thisMethodName = nameof(InstancePropertyTestRunner.AccessFromNestedMethodSequence); + + InitProperties(thisMethodName); + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == Prop1.NameField); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "Field"); + + var result = Execute1(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute2(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute3(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.NameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "Prop"); + + result = Execute1(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute2(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute3(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseField"); + + result = Execute1(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute2(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute3(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + result = Execute1(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute2(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute3(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + + IEnumerable Execute1() + { + return session.Query.Execute(cachingKey, (q) => query, Prop1); + } + IEnumerable Execute2() + { + return session.Query.Execute(cachingKey, (q) => query, Prop2); + } + IEnumerable Execute3() + { + return session.Query.Execute(cachingKey, (q) => query, Prop3); + } + } + + public void AccessFromNestedMethodOrderedSequence(Session session) + { + var thisMethodName = nameof(InstancePropertyTestRunner.AccessFromNestedMethodOrderedSequence); + + InitProperties(thisMethodName); + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == Prop1.NameField); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "Field"); + + var result = Execute1(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute2(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute3(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.NameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "Prop"); + + result = Execute1(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute2(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute3(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseField"); + + result = Execute1(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute2(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute3(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + result = Execute1(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute2(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute3(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + + IEnumerable Execute1() + { + return session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), Prop1); + } + IEnumerable Execute2() + { + return session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), Prop2); + } + IEnumerable Execute3() + { + return session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), Prop3); + } + } + + public void AccessFromLocalFuncScalar(Session session) + { + var thisMethodName = nameof(InstancePropertyTestRunner.AccessFromLocalFuncScalar); + + InitProperties(thisMethodName); + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == Prop1.NameField); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "Field"); + +#pragma warning disable IDE0039 // Use local function + Func execute1 = () => session.Query.Execute(cachingKey, (q) => query.Count(), Prop1); + Func execute2 = () => session.Query.Execute(cachingKey, (q) => query.Count(), Prop2); + Func execute3 = () => session.Query.Execute(cachingKey, (q) => query.Count(), Prop3); +#pragma warning restore IDE0039 // Use local function + + var result = execute1.Invoke(); + Assert.That(result, Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result, Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.NameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "Prop"); + + result = execute1.Invoke(); + Assert.That(result, Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result, Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseField"); + + result = execute1.Invoke(); + Assert.That(result, Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result, Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + result = execute1.Invoke(); + Assert.That(result, Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result, Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + public void AccessFromLocalFuncSequence(Session session) + { + var thisMethodName = nameof(InstancePropertyTestRunner.AccessFromLocalFuncSequence); + + InitProperties(thisMethodName); + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == Prop1.NameField); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "Field"); + +#pragma warning disable IDE0039 // Use local function + Func> execute1 = () => session.Query.Execute(cachingKey, (q) => query, Prop1); + Func> execute2 = () => session.Query.Execute(cachingKey, (q) => query, Prop2); + Func> execute3 = () => session.Query.Execute(cachingKey, (q) => query, Prop3); +#pragma warning restore IDE0039 // Use local function + + var result = execute1.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.NameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "Prop"); + + result = execute1.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseField"); + + result = execute1.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + result = execute1.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + public void AccessFromLocalFuncOrderedSequence(Session session) + { + var thisMethodName = nameof(InstancePropertyTestRunner.AccessFromLocalFuncOrderedSequence); + + InitProperties(thisMethodName); + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == Prop1.NameField); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "Field"); + +#pragma warning disable IDE0039 // Use local function + Func> execute1 = () => session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), Prop1); + Func> execute2 = () => session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), Prop2); + Func> execute3 = () => session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), Prop3); +#pragma warning restore IDE0039 // Use local function + + var result = execute1.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.NameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "Prop"); + + result = execute1.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseField"); + + result = execute1.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + result = execute1.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + public void CacheAcrossMethodsScalar(Session session) + { + var thisMethodName = nameof(InstancePropertyTestRunner.CacheAcrossMethodsScalar); + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var sharedQueryable = session.Query.All().Where(q => q.Name == Prop1.BaseNameProp); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + var result = ScalarMethod1(session, cachingKey, sharedQueryable); + Assert.That(result, Is.EqualTo(1)); + result = ScalarMethod2(session, cachingKey, sharedQueryable); + Assert.That(result, Is.EqualTo(1)); + result = ScalarMethod3(session, cachingKey, sharedQueryable); + Assert.That(result, Is.EqualTo(1)); + + var queryable1 = session.Query.All().Where(q => q.Name == Prop1.BaseNameProp); + var queryable2 = session.Query.All().Where(q => q.Name == Prop1.BaseNameProp); + var queryable3 = session.Query.All().Where(q => q.Name == Prop1.BaseNameProp); + + result = ScalarMethod1(session, cachingKey, queryable1); + Assert.That(result, Is.EqualTo(1)); + result = ScalarMethod1(session, cachingKey, queryable2); + Assert.That(result, Is.EqualTo(1)); + result = ScalarMethod1(session, cachingKey, queryable3); + Assert.That(result, Is.EqualTo(1)); + + result = ScalarMethod2(session, cachingKey, queryable1); + Assert.That(result, Is.EqualTo(1)); + result = ScalarMethod2(session, cachingKey, queryable2); + Assert.That(result, Is.EqualTo(1)); + result = ScalarMethod2(session, cachingKey, queryable3); + Assert.That(result, Is.EqualTo(1)); + + result = ScalarMethod3(session, cachingKey, queryable1); + Assert.That(result, Is.EqualTo(1)); + result = ScalarMethod3(session, cachingKey, queryable2); + Assert.That(result, Is.EqualTo(1)); + result = ScalarMethod3(session, cachingKey, queryable3); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + } + + public void CacheAcrossMethodsSequence(Session session) + { + var thisMethodName = nameof(InstancePropertyTestRunner.CacheAcrossMethodsSequence); + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var sharedQueryable = session.Query.All().Where(q => q.Name == Prop1.BaseNameProp); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + var result = SequenceMethod1(session, cachingKey, sharedQueryable); + Assert.That(result.Count(), Is.EqualTo(1)); + result = SequenceMethod2(session, cachingKey, sharedQueryable); + Assert.That(result.Count(), Is.EqualTo(1)); + result = SequenceMethod3(session, cachingKey, sharedQueryable); + Assert.That(result.Count(), Is.EqualTo(1)); + + var queryable1 = session.Query.All().Where(q => q.Name == Prop1.BaseNameProp); + var queryable2 = session.Query.All().Where(q => q.Name == Prop1.BaseNameProp); + var queryable3 = session.Query.All().Where(q => q.Name == Prop1.BaseNameProp); + + result = SequenceMethod1(session, cachingKey, queryable1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = SequenceMethod1(session, cachingKey, queryable2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = SequenceMethod1(session, cachingKey, queryable3); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = SequenceMethod2(session, cachingKey, queryable1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = SequenceMethod2(session, cachingKey, queryable2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = SequenceMethod2(session, cachingKey, queryable3); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = SequenceMethod3(session, cachingKey, queryable1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = SequenceMethod3(session, cachingKey, queryable2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = SequenceMethod3(session, cachingKey, queryable3); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + } + + public void CacheAcrossMethodsOrderedSequence(Session session) + { + var thisMethodName = nameof(InstancePropertyTestRunner.CacheAcrossMethodsOrderedSequence); + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var sharedQueryable = session.Query.All().Where(q => q.Name == Prop1.BaseNameProp); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + var result = OrderedSequenceMethod1(session, cachingKey, sharedQueryable); + Assert.That(result.Count(), Is.EqualTo(1)); + result = OrderedSequenceMethod2(session, cachingKey, sharedQueryable); + Assert.That(result.Count(), Is.EqualTo(1)); + result = OrderedSequenceMethod3(session, cachingKey, sharedQueryable); + Assert.That(result.Count(), Is.EqualTo(1)); + + var queryable1 = session.Query.All().Where(q => q.Name == Prop1.BaseNameProp); + var queryable2 = session.Query.All().Where(q => q.Name == Prop1.BaseNameProp); + var queryable3 = session.Query.All().Where(q => q.Name == Prop1.BaseNameProp); + + result = OrderedSequenceMethod1(session, cachingKey, queryable1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = OrderedSequenceMethod1(session, cachingKey, queryable2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = OrderedSequenceMethod1(session, cachingKey, queryable3); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = OrderedSequenceMethod2(session, cachingKey, queryable1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = OrderedSequenceMethod2(session, cachingKey, queryable2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = OrderedSequenceMethod2(session, cachingKey, queryable3); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = OrderedSequenceMethod3(session, cachingKey, queryable1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = OrderedSequenceMethod3(session, cachingKey, queryable2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = OrderedSequenceMethod3(session, cachingKey, queryable3); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + } + + private int ScalarMethod1(Session session, string cachingKey, IQueryable query) => + session.Query.Execute(cachingKey, (q) => query.Count(), Prop1); + + private int ScalarMethod2(Session session, string cachingKey, IQueryable query) => + session.Query.Execute(cachingKey, (q) => query.Count(), Prop2); + + private int ScalarMethod3(Session session, string cachingKey, IQueryable query) => + session.Query.Execute(cachingKey, (q) => query.Count(), Prop3); + + private IEnumerable SequenceMethod1(Session session, string cachingKey, IQueryable query) => + session.Query.Execute(cachingKey, (q) => query, Prop1); + + private IEnumerable SequenceMethod2(Session session, string cachingKey, IQueryable query) => + session.Query.Execute(cachingKey, (q) => query, Prop2); + + private IEnumerable SequenceMethod3(Session session, string cachingKey, IQueryable query) => + session.Query.Execute(cachingKey, (q) => query, Prop3); + + private IEnumerable OrderedSequenceMethod1(Session session, string cachingKey, IQueryable query) => + session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), Prop1); + + private IEnumerable OrderedSequenceMethod2(Session session, string cachingKey, IQueryable query) => + session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), Prop2); + + private IEnumerable OrderedSequenceMethod3(Session session, string cachingKey, IQueryable query) => + session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), Prop3); + + private void InitProperties(string methodName) + { + Prop1 = new ParameterContainer() { + BaseNameField = ThisClassName + methodName + "BaseField1", + BaseNameProp = ThisClassName + methodName + "BaseProp1", + NameField = ThisClassName + methodName + "Field1", + NameProp = ThisClassName + methodName + "Prop1", + }; + Prop2 = new ParameterContainer() { + BaseNameField = ThisClassName + methodName + "BaseField2", + BaseNameProp = ThisClassName + methodName + "BaseProp2", + NameField = ThisClassName + methodName + "Field2", + NameProp = ThisClassName + methodName + "Prop2", + }; + Prop3 = new ParameterContainer() { + BaseNameField = ThisClassName + methodName + "BaseField3", + BaseNameProp = ThisClassName + methodName + "BaseProp3", + NameField = ThisClassName + methodName + "Field3", + NameProp = ThisClassName + methodName + "Prop3", + }; + } + } +} diff --git a/Orm/Xtensive.Orm.Tests/Storage/CustomClosureForCachingQueries/TestRunners.LocalVariableTestRunner.cs b/Orm/Xtensive.Orm.Tests/Storage/CustomClosureForCachingQueries/TestRunners.LocalVariableTestRunner.cs new file mode 100644 index 0000000000..0b797f7621 --- /dev/null +++ b/Orm/Xtensive.Orm.Tests/Storage/CustomClosureForCachingQueries/TestRunners.LocalVariableTestRunner.cs @@ -0,0 +1,595 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NUnit.Framework; +using Xtensive.Orm.Tests.Storage.InlineQueriesCachingTestModel; + +namespace Xtensive.Orm.Tests.Storage.InlineQueriesCachingTestModel.TestRunners +{ + public class LocalVariableTestRunner : TestRunnerBase + { + private readonly static string thisClassName = nameof(LocalVariableTestRunner); + + protected override string ThisClassName => thisClassName; + + public void GeneralAccessScalar(Session session) + { + var thisMethodName = nameof(LocalVariableTestRunner.GeneralAccessScalar); + +#pragma warning disable IDE0018 // Inline variable declaration + ParameterContainer local1, local2, local3; + InitVariables(thisMethodName, out local1, out local2, out local3); +#pragma warning restore IDE0018 // Inline variable declaration + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == local1.NameField); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "Field"); + + var result = session.Query.Execute(cachingKey, (q) => query.Count(), local1); + Assert.That(result, Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.Count(), local2); + Assert.That(result, Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.Count(), local2); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == local1.NameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "Prop"); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), local1); + Assert.That(result, Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.Count(), local2); + Assert.That(result, Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.Count(), local2); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == local1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseField"); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), local1); + Assert.That(result, Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.Count(), local2); + Assert.That(result, Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.Count(), local2); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == local1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), local1); + Assert.That(result, Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.Count(), local2); + Assert.That(result, Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.Count(), local2); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + public void GeneralAccessSequence(Session session) + { + var thisMethodName = nameof(LocalVariableTestRunner.GeneralAccessSequence); + +#pragma warning disable IDE0018 // Inline variable declaration + ParameterContainer local1, local2, local3; + InitVariables(thisMethodName, out local1, out local2, out local3); +#pragma warning restore IDE0018 // Inline variable declaration + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == local1.NameField); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "Field"); + + var result = session.Query.Execute(cachingKey, (q) => query, local1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query, local2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query, local2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == local1.NameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "Prop"); + + result = session.Query.Execute(cachingKey, (q) => query, local1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query, local2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query, local2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == local1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseField"); + + result = session.Query.Execute(cachingKey, (q) => query, local1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query, local2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query, local2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == local1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + result = session.Query.Execute(cachingKey, (q) => query, local1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query, local2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query, local2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + public void GeneralAccessOrderedSequence(Session session) + { + var thisMethodName = nameof(LocalVariableTestRunner.GeneralAccessOrderedSequence); + +#pragma warning disable IDE0018 // Inline variable declaration + ParameterContainer local1, local2, local3; + InitVariables(thisMethodName, out local1, out local2, out local3); +#pragma warning restore IDE0018 // Inline variable declaration + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == local1.NameField); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "Field"); + + var result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), local1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), local2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), local2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == local1.NameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "Prop"); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), local1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), local2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), local2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == local1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseField"); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), local1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), local2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), local2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == local1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), local1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), local2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), local2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + public void AccessFromNestedMethodScalar(Session session) + { + var thisMethodName = nameof(LocalVariableTestRunner.AccessFromNestedMethodScalar); + +#pragma warning disable IDE0018 // Inline variable declaration + ParameterContainer local1, local2, local3; + InitVariables(thisMethodName, out local1, out local2, out local3); +#pragma warning restore IDE0018 // Inline variable declaration + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == local1.NameField); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "Field"); + + var result = Execute1(); + Assert.That(result, Is.EqualTo(1)); + result = Execute2(); + Assert.That(result, Is.EqualTo(1)); + result = Execute3(); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == local1.NameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "Prop"); + + result = Execute1(); + Assert.That(result, Is.EqualTo(1)); + result = Execute2(); + Assert.That(result, Is.EqualTo(1)); + result = Execute3(); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == local1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseField"); + + result = Execute1(); + Assert.That(result, Is.EqualTo(1)); + result = Execute2(); + Assert.That(result, Is.EqualTo(1)); + result = Execute3(); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == local1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + result = Execute1(); + Assert.That(result, Is.EqualTo(1)); + result = Execute2(); + Assert.That(result, Is.EqualTo(1)); + result = Execute3(); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + + int Execute1() + { + return session.Query.Execute(cachingKey, (q) => query.Count(), local1); + } + int Execute2() + { + return session.Query.Execute(cachingKey, (q) => query.Count(), local2); + } + int Execute3() + { + return session.Query.Execute(cachingKey, (q) => query.Count(), local3); + } + } + + public void AccessFromNestedMethodSequence(Session session) + { + var thisMethodName = nameof(LocalVariableTestRunner.AccessFromNestedMethodSequence); + +#pragma warning disable IDE0018 // Inline variable declaration + ParameterContainer local1, local2, local3; + InitVariables(thisMethodName, out local1, out local2, out local3); +#pragma warning restore IDE0018 // Inline variable declaration + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == local1.NameField); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "Field"); + + var result = Execute1(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute2(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute3(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == local1.NameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "Prop"); + + result = Execute1(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute2(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute3(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == local1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseField"); + + result = Execute1(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute2(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute3(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == local1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + result = Execute1(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute2(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute3(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + + IEnumerable Execute1() + { + return session.Query.Execute(cachingKey, (q) => query, local1); + } + IEnumerable Execute2() + { + return session.Query.Execute(cachingKey, (q) => query, local2); + } + IEnumerable Execute3() + { + return session.Query.Execute(cachingKey, (q) => query, local3); + } + } + + public void AccessFromNestedMethodOrderedSequence(Session session) + { + var thisMethodName = nameof(LocalVariableTestRunner.AccessFromNestedMethodOrderedSequence); + +#pragma warning disable IDE0018 // Inline variable declaration + ParameterContainer local1, local2, local3; + InitVariables(thisMethodName, out local1, out local2, out local3); +#pragma warning restore IDE0018 // Inline variable declaration + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == local1.NameField); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "Field"); + + var result = Execute1(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute2(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute3(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == local1.NameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "Prop"); + + result = Execute1(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute2(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute3(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == local1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseField"); + + result = Execute1(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute2(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute3(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == local1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + result = Execute1(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute2(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute3(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + + IEnumerable Execute1() + { + return session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), local1); + } + IEnumerable Execute2() + { + return session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), local2); + } + IEnumerable Execute3() + { + return session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), local3); + } + } + + public void AccessFromLocalFuncScalar(Session session) + { + var thisMethodName = nameof(LocalVariableTestRunner.AccessFromLocalFuncScalar); + +#pragma warning disable IDE0018 // Inline variable declaration + ParameterContainer local1, local2, local3; + InitVariables(thisMethodName, out local1, out local2, out local3); +#pragma warning restore IDE0018 // Inline variable declaration + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == local1.NameField); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "Field"); + +#pragma warning disable IDE0039 // Use local function + Func execute1 = () => session.Query.Execute(cachingKey, (q) => query.Count(), local1); + Func execute2 = () => session.Query.Execute(cachingKey, (q) => query.Count(), local2); + Func execute3 = () => session.Query.Execute(cachingKey, (q) => query.Count(), local3); +#pragma warning restore IDE0039 // Use local function + + var result = execute1.Invoke(); + Assert.That(result, Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result, Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == local1.NameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "Prop"); + + result = execute1.Invoke(); + Assert.That(result, Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result, Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == local1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseField"); + + result = execute1.Invoke(); + Assert.That(result, Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result, Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == local1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + result = execute1.Invoke(); + Assert.That(result, Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result, Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + public void AccessFromLocalFuncSequence(Session session) + { + var thisMethodName = nameof(LocalVariableTestRunner.AccessFromLocalFuncSequence); + +#pragma warning disable IDE0018 // Inline variable declaration + ParameterContainer local1, local2, local3; + InitVariables(thisMethodName, out local1, out local2, out local3); +#pragma warning restore IDE0018 // Inline variable declaration + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == local1.NameField); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "Field"); + +#pragma warning disable IDE0039 // Use local function + Func> execute1 = () => session.Query.Execute(cachingKey, (q) => query, local1); + Func> execute2 = () => session.Query.Execute(cachingKey, (q) => query, local2); + Func> execute3 = () => session.Query.Execute(cachingKey, (q) => query, local3); +#pragma warning restore IDE0039 // Use local function + + var result = execute1.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == local1.NameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "Prop"); + + result = execute1.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == local1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseField"); + + result = execute1.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == local1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + result = execute1.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + public void AccessFromLocalFuncOrderedSequence(Session session) + { + var thisMethodName = nameof(LocalVariableTestRunner.AccessFromLocalFuncOrderedSequence); + +#pragma warning disable IDE0018 // Inline variable declaration + ParameterContainer local1, local2, local3; + InitVariables(thisMethodName, out local1, out local2, out local3); +#pragma warning restore IDE0018 // Inline variable declaration + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == local1.NameField); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "Field"); + +#pragma warning disable IDE0039 // Use local function + Func> execute1 = () => session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), local1); + Func> execute2 = () => session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), local2); + Func> execute3 = () => session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), local3); +#pragma warning restore IDE0039 // Use local function + + var result = execute1.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == local1.NameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "Prop"); + + result = execute1.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == local1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseField"); + + result = execute1.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == local1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + result = execute1.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + } +} diff --git a/Orm/Xtensive.Orm.Tests/Storage/CustomClosureForCachingQueries/TestRunners.NestedClassTestRunner.cs b/Orm/Xtensive.Orm.Tests/Storage/CustomClosureForCachingQueries/TestRunners.NestedClassTestRunner.cs new file mode 100644 index 0000000000..e6b371c6e0 --- /dev/null +++ b/Orm/Xtensive.Orm.Tests/Storage/CustomClosureForCachingQueries/TestRunners.NestedClassTestRunner.cs @@ -0,0 +1,1378 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NUnit.Framework; +using Xtensive.Orm.Tests.Storage.InlineQueriesCachingTestModel; + +namespace Xtensive.Orm.Tests.Storage.InlineQueriesCachingTestModel.TestRunners +{ + public class NestedClassTestRunner : TestRunnerBase + { + public class NestedClass + { + private string methodName; + + public static ParameterContainer StaticField1; + public static ParameterContainer StaticField2; + + public ParameterContainer Field1; + public ParameterContainer Field2; + + public static ParameterContainer StaticProp1 { get; set; } + public static ParameterContainer StaticProp2 { get; set; } + + public ParameterContainer Prop1 { get; set; } + public ParameterContainer Prop2 { get; set; } + + public void StaticFieldScalarTest(Session session) + { + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == StaticField1.BaseNameField); + var cachingKey = ComposeKey(nameof(NestedClass), methodName, "BaseField"); + + var result = session.Query.Execute(cachingKey, (q) => query.Count(), StaticField1); + Assert.That(result, Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), StaticField2); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == StaticField1.BaseNameProp); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "BaseProp"); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), StaticField1); + Assert.That(result, Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), StaticField2); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == StaticField1.NameField); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "Field"); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), StaticField1); + Assert.That(result, Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), StaticField2); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == StaticField1.NameProp); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "Prop"); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), StaticField1); + Assert.That(result, Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), StaticField2); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + public void StaticFieldSequenceTest(Session session) + { + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == StaticField1.BaseNameField); + var cachingKey = ComposeKey(nameof(NestedClass), methodName, "BaseField"); + + var result = session.Query.Execute(cachingKey, (q) => query, StaticField1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query, StaticField2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == StaticField1.BaseNameProp); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "BaseProp"); + + result = session.Query.Execute(cachingKey, (q) => query, StaticField1); + Assert.That(result, Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query, StaticField2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == StaticField1.NameField); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "Field"); + + result = session.Query.Execute(cachingKey, (q) => query, StaticField1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query, StaticField2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == StaticField1.NameProp); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "Prop"); + + result = session.Query.Execute(cachingKey, (q) => query, StaticField1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query, StaticField2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + public void StaticFieldOrderedSequenceTest(Session session) + { + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == StaticField1.BaseNameField); + var cachingKey = ComposeKey(nameof(NestedClass), methodName, "BaseField"); + + var result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), StaticField1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), StaticField2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == StaticField1.BaseNameProp); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "BaseProp"); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), StaticField1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), StaticField2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == StaticField1.NameField); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "Field"); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), StaticField1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), StaticField2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == StaticField1.NameProp); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "Prop"); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), StaticField1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e=>e.Id), StaticField2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + public void StaticPropertyScalarTest(Session session) + { + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == StaticProp1.BaseNameField); + var cachingKey = ComposeKey(nameof(NestedClass), methodName, "BaseField"); + + var result = session.Query.Execute(cachingKey, (q) => query.Count(), StaticProp1); + Assert.That(result, Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), StaticProp2); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == StaticProp1.BaseNameProp); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "BaseProp"); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), StaticProp1); + Assert.That(result, Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), StaticProp2); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == StaticProp1.NameField); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "Field"); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), StaticProp1); + Assert.That(result, Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), StaticProp2); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == StaticProp1.NameProp); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "Prop"); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), StaticProp1); + Assert.That(result, Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), StaticProp2); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + } + + public void StaticPropertySequenceTest(Session session) + { + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == StaticProp1.BaseNameField); + var cachingKey = ComposeKey(nameof(NestedClass), methodName, "BaseField"); + + var result = session.Query.Execute(cachingKey, (q) => query, StaticProp1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query, StaticProp2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == StaticProp1.BaseNameProp); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "BaseProp"); + + result = session.Query.Execute(cachingKey, (q) => query, StaticProp1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query, StaticProp2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == StaticProp1.NameField); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "Field"); + + result = session.Query.Execute(cachingKey, (q) => query, StaticProp1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query, StaticProp2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == StaticProp1.NameProp); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "Prop"); + + result = session.Query.Execute(cachingKey, (q) => query, StaticProp1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query, StaticProp2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + } + + public void StaticPropertyOrderedSequenceTest(Session session) + { + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == StaticProp1.BaseNameField); + var cachingKey = ComposeKey(nameof(NestedClass), methodName, "BaseField"); + + var result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), StaticProp1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), StaticProp2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == StaticProp1.BaseNameProp); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "BaseProp"); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), StaticProp1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), StaticProp2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == StaticProp1.NameField); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "Field"); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), StaticProp1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), StaticProp2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == StaticProp1.NameProp); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "Prop"); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), StaticProp1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), StaticProp2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + } + + public void FieldTest(Session session) + { + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == Field1.BaseNameField); + var cachingKey = ComposeKey(nameof(NestedClass), methodName, "BaseField"); + + var result = session.Query.Execute(cachingKey, (q) => query.Count(), Field1); + Assert.That(result, Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), Field2); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Field1.BaseNameProp); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "BaseProp"); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), Field1); + Assert.That(result, Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), Field2); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Field1.NameField); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "Field"); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), Field1); + Assert.That(result, Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), Field2); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Field1.NameProp); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "Prop"); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), Field1); + Assert.That(result, Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), Field2); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + public void FieldScalarTest(Session session) + { + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == Field1.BaseNameField); + var cachingKey = ComposeKey(nameof(NestedClass), methodName, "BaseField"); + + var result = session.Query.Execute(cachingKey, (q) => query.Count(), Field1); + Assert.That(result, Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), Field2); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Field1.BaseNameProp); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "BaseProp"); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), Field1); + Assert.That(result, Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), Field2); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Field1.NameField); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "Field"); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), Field1); + Assert.That(result, Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), Field2); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Field1.NameProp); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "Prop"); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), Field1); + Assert.That(result, Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), Field2); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + public void FieldSequenceTest(Session session) + { + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == Field1.BaseNameField); + var cachingKey = ComposeKey(nameof(NestedClass), methodName, "BaseField"); + + var result = session.Query.Execute(cachingKey, (q) => query.Count(), Field1); + Assert.That(result, Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), Field2); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Field1.BaseNameProp); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "BaseProp"); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), Field1); + Assert.That(result, Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), Field2); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Field1.NameField); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "Field"); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), Field1); + Assert.That(result, Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), Field2); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Field1.NameProp); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "Prop"); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), Field1); + Assert.That(result, Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), Field2); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + public void FieldOrderedSequenceTest(Session session) + { + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == Field1.BaseNameField); + var cachingKey = ComposeKey(nameof(NestedClass), methodName, "BaseField"); + + var result = session.Query.Execute(cachingKey, (q) => query.Count(), Field1); + Assert.That(result, Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), Field2); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Field1.BaseNameProp); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "BaseProp"); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), Field1); + Assert.That(result, Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), Field2); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Field1.NameField); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "Field"); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), Field1); + Assert.That(result, Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), Field2); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Field1.NameProp); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "Prop"); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), Field1); + Assert.That(result, Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), Field2); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + public void PropertyScalarTest(Session session) + { + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == Prop1.BaseNameField); + var cachingKey = ComposeKey(nameof(NestedClass), methodName, "BaseField"); + + var result = session.Query.Execute(cachingKey, (q) => query.Count(), Prop1); + Assert.That(result, Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), Prop2); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.BaseNameProp); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "BaseProp"); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), Prop1); + Assert.That(result, Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), Prop2); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.NameField); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "Field"); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), Prop1); + Assert.That(result, Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), Prop2); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.NameProp); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "Prop"); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), Prop1); + Assert.That(result, Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), Prop2); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + public void PropertySequenceTest(Session session) + { + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == Prop1.BaseNameField); + var cachingKey = ComposeKey(nameof(NestedClass), methodName, "BaseField"); + + var result = session.Query.Execute(cachingKey, (q) => query, Prop1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query, Prop2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.BaseNameProp); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "BaseProp"); + + result = session.Query.Execute(cachingKey, (q) => query, Prop1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query, Prop2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.NameField); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "Field"); + + result = session.Query.Execute(cachingKey, (q) => query, Prop1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query, Prop2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.NameProp); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "Prop"); + + result = session.Query.Execute(cachingKey, (q) => query, Prop1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query, Prop2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + public void PropertyOrderedSequenceTest(Session session) + { + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == Prop1.BaseNameField); + var cachingKey = ComposeKey(nameof(NestedClass), methodName, "BaseField"); + + var result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), Prop1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), Prop2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.BaseNameProp); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "BaseProp"); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), Prop1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), Prop2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.NameField); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "Field"); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), Prop1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), Prop2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.NameProp); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "Prop"); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), Prop1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), Prop2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + public void InitContainers(string methodName) + { + this.methodName = methodName; + + StaticField1 = new ParameterContainer() { + BaseNameField = NestedClassTestRunner.thisClassName + methodName + "BaseField1", + BaseNameProp = NestedClassTestRunner.thisClassName + methodName + "BaseProp1", + NameField = NestedClassTestRunner.thisClassName + methodName + "Field1", + NameProp = NestedClassTestRunner.thisClassName + methodName + "Prop1", + }; + StaticField2 = new ParameterContainer() { + BaseNameField = NestedClassTestRunner.thisClassName + methodName + "BaseField2", + BaseNameProp = NestedClassTestRunner.thisClassName + methodName + "BaseProp2", + NameField = NestedClassTestRunner.thisClassName + methodName + "Field2", + NameProp = NestedClassTestRunner.thisClassName + methodName + "Prop2", + }; + + StaticProp1 = new ParameterContainer() { + BaseNameField = NestedClassTestRunner.thisClassName + methodName + "BaseField3", + BaseNameProp = NestedClassTestRunner.thisClassName + methodName + "BaseProp3", + NameField = NestedClassTestRunner.thisClassName + methodName + "Field3", + NameProp = NestedClassTestRunner.thisClassName + methodName + "Prop3", + }; + StaticField2 = new ParameterContainer() { + BaseNameField = NestedClassTestRunner.thisClassName + methodName + "BaseField4", + BaseNameProp = NestedClassTestRunner.thisClassName + methodName + "BaseProp4", + NameField = NestedClassTestRunner.thisClassName + methodName + "Field4", + NameProp = NestedClassTestRunner.thisClassName + methodName + "Prop4", + }; + + Field1 = new ParameterContainer() { + BaseNameField = NestedClassTestRunner.thisClassName + methodName + "BaseField5", + BaseNameProp = NestedClassTestRunner.thisClassName + methodName + "BaseProp5", + NameField = NestedClassTestRunner.thisClassName + methodName + "Field5", + NameProp = NestedClassTestRunner.thisClassName + methodName + "Prop5", + }; + Field2 = new ParameterContainer() { + BaseNameField = NestedClassTestRunner.thisClassName + methodName + "BaseField6", + BaseNameProp = NestedClassTestRunner.thisClassName + methodName + "BaseProp6", + NameField = NestedClassTestRunner.thisClassName + methodName + "Field6", + NameProp = NestedClassTestRunner.thisClassName + methodName + "Prop6", + }; + + Prop1 = new ParameterContainer() { + BaseNameField = NestedClassTestRunner.thisClassName + methodName + "BaseField7", + BaseNameProp = NestedClassTestRunner.thisClassName + methodName + "BaseProp7", + NameField = NestedClassTestRunner.thisClassName + methodName + "Field7", + NameProp = NestedClassTestRunner.thisClassName + methodName + "Prop7", + }; + Prop2 = new ParameterContainer() { + BaseNameField = NestedClassTestRunner.thisClassName + methodName + "BaseField8", + BaseNameProp = NestedClassTestRunner.thisClassName + methodName + "BaseProp8", + NameField = NestedClassTestRunner.thisClassName + methodName + "Field8", + NameProp = NestedClassTestRunner.thisClassName + methodName + "Prop8", + }; + } + } + + private static readonly string thisClassName = nameof(NestedClassTestRunner); + + + protected override string ThisClassName => thisClassName; + + public void AccessInsideNestedClassTest(Session session) + { + var nestedClass = new NestedClass(); + nestedClass.InitContainers(nameof(NestedClassTestRunner.AccessInsideNestedClassTest)); + + nestedClass.StaticFieldScalarTest(session); + nestedClass.StaticFieldSequenceTest(session); + nestedClass.StaticFieldOrderedSequenceTest(session); + + nestedClass.StaticPropertyScalarTest(session); + nestedClass.StaticPropertySequenceTest(session); + nestedClass.StaticPropertyOrderedSequenceTest(session); + + nestedClass.FieldScalarTest(session); + nestedClass.FieldSequenceTest(session); + nestedClass.FieldOrderedSequenceTest(session); + + nestedClass.PropertyScalarTest(session); + nestedClass.PropertySequenceTest(session); + nestedClass.PropertyOrderedSequenceTest(session); + } + + public void AccessOutideNestedClassTest(Session session) + { + StaticFieldScalarTest(session); + + StaticPropertyScalarTest(session); + } + + private void StaticFieldScalarTest(Session session) + { + var nestedClass = new NestedClass(); + nestedClass.InitContainers(nameof(NestedClassTestRunner.AccessInsideNestedClassTest)); + + //staticFields + var methodName = "StaticFieldTest"; + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == NestedClass.StaticField1.BaseNameField); + var cachingKey = ComposeKey(nameof(NestedClass), methodName, "BaseField1"); + + var result = session.Query.Execute(cachingKey, (q) => query.Count(), NestedClass.StaticField1); + Assert.That(result, Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), NestedClass.StaticField2); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == NestedClass.StaticField1.BaseNameProp); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "BaseProp1"); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), NestedClass.StaticField1); + Assert.That(result, Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), NestedClass.StaticField2); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == NestedClass.StaticField1.NameField); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "Field1"); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), NestedClass.StaticField1); + Assert.That(result, Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), NestedClass.StaticField2); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == NestedClass.StaticField1.NameProp); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "Prop1"); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), NestedClass.StaticField1); + Assert.That(result, Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), NestedClass.StaticField2); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + } + + private void StaticFieldSequenceTest(Session session) + { + var nestedClass = new NestedClass(); + nestedClass.InitContainers(nameof(NestedClassTestRunner.AccessInsideNestedClassTest)); + + //staticFields + var methodName = "StaticFieldTest"; + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == NestedClass.StaticField1.BaseNameField); + var cachingKey = ComposeKey(nameof(NestedClass), methodName, "BaseField1"); + + var result = session.Query.Execute(cachingKey, (q) => query, NestedClass.StaticField1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query, NestedClass.StaticField2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == NestedClass.StaticField1.BaseNameProp); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "BaseProp1"); + + result = session.Query.Execute(cachingKey, (q) => query, NestedClass.StaticField1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query, NestedClass.StaticField2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == NestedClass.StaticField1.NameField); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "Field1"); + + result = session.Query.Execute(cachingKey, (q) => query, NestedClass.StaticField1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query, NestedClass.StaticField2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == NestedClass.StaticField1.NameProp); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "Prop1"); + + result = session.Query.Execute(cachingKey, (q) => query, NestedClass.StaticField1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query, NestedClass.StaticField2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + } + + private void StaticFieldOrderedSequenceTest(Session session) + { + var nestedClass = new NestedClass(); + nestedClass.InitContainers(nameof(NestedClassTestRunner.AccessInsideNestedClassTest)); + + //staticFields + var methodName = "StaticFieldTest"; + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == NestedClass.StaticField1.BaseNameField); + var cachingKey = ComposeKey(nameof(NestedClass), methodName, "BaseField1"); + + var result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), NestedClass.StaticField1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), NestedClass.StaticField2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == NestedClass.StaticField1.BaseNameProp); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "BaseProp1"); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), NestedClass.StaticField1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), NestedClass.StaticField2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == NestedClass.StaticField1.NameField); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "Field1"); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), NestedClass.StaticField1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), NestedClass.StaticField2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == NestedClass.StaticField1.NameProp); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "Prop1"); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), NestedClass.StaticField1); + Assert.That(result.Count, Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), NestedClass.StaticField2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + } + + private void StaticPropertyScalarTest(Session session) + { + var nestedClass = new NestedClass(); + nestedClass.InitContainers(nameof(NestedClassTestRunner.AccessInsideNestedClassTest)); + + // static properties + var methodName = "StaticPropertyTest"; + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == NestedClass.StaticProp1.BaseNameField); + var cachingKey = ComposeKey(nameof(NestedClass), methodName, "BaseField2"); + + var result = session.Query.Execute(cachingKey, (q) => query.Count(), NestedClass.StaticProp1); + Assert.That(result, Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), NestedClass.StaticProp2); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == NestedClass.StaticProp1.BaseNameProp); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "BaseProp2"); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), NestedClass.StaticProp1); + Assert.That(result, Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), NestedClass.StaticProp2); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == NestedClass.StaticProp1.NameField); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "Field2"); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), NestedClass.StaticProp1); + Assert.That(result, Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), NestedClass.StaticProp2); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == NestedClass.StaticProp1.NameProp); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "Prop2"); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), NestedClass.StaticProp1); + Assert.That(result, Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), NestedClass.StaticProp2); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + } + + private void StaticPropertySequenceTest(Session session) + { + var nestedClass = new NestedClass(); + nestedClass.InitContainers(nameof(NestedClassTestRunner.AccessInsideNestedClassTest)); + + // static properties + var methodName = "StaticPropertyTest"; + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == NestedClass.StaticProp1.BaseNameField); + var cachingKey = ComposeKey(nameof(NestedClass), methodName, "BaseField2"); + + var result = session.Query.Execute(cachingKey, (q) => query, NestedClass.StaticProp1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query, NestedClass.StaticProp2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == NestedClass.StaticProp1.BaseNameProp); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "BaseProp2"); + + result = session.Query.Execute(cachingKey, (q) => query, NestedClass.StaticProp1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query, NestedClass.StaticProp2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == NestedClass.StaticProp1.NameField); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "Field2"); + + result = session.Query.Execute(cachingKey, (q) => query, NestedClass.StaticProp1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query, NestedClass.StaticProp2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == NestedClass.StaticProp1.NameProp); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "Prop2"); + + result = session.Query.Execute(cachingKey, (q) => query, NestedClass.StaticProp1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query, NestedClass.StaticProp2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + } + + private void StaticPropertyOrderedSequenceTest(Session session) + { + var nestedClass = new NestedClass(); + nestedClass.InitContainers(nameof(NestedClassTestRunner.AccessInsideNestedClassTest)); + + // static properties + var methodName = "StaticPropertyTest"; + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == NestedClass.StaticProp1.BaseNameField); + var cachingKey = ComposeKey(nameof(NestedClass), methodName, "BaseField2"); + + var result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), NestedClass.StaticProp1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), NestedClass.StaticProp2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == NestedClass.StaticProp1.BaseNameProp); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "BaseProp2"); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), NestedClass.StaticProp1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), NestedClass.StaticProp2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == NestedClass.StaticProp1.NameField); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "Field2"); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), NestedClass.StaticProp1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), NestedClass.StaticProp2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == NestedClass.StaticProp1.NameProp); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "Prop2"); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), NestedClass.StaticProp1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), NestedClass.StaticProp2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + } + + private void FieldScalarTest(Session session) + { + var nestedClass = new NestedClass(); + nestedClass.InitContainers(nameof(NestedClassTestRunner.AccessInsideNestedClassTest)); + + //fields + var methodName = "FieldTest"; + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == nestedClass.Field1.BaseNameField); + var cachingKey = ComposeKey(nameof(NestedClass), methodName, "BaseField3"); + + var result = session.Query.Execute(cachingKey, (q) => query.Count(), nestedClass.Field1); + Assert.That(result, Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), nestedClass.Field2); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == nestedClass.Field1.BaseNameProp); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "BaseProp3"); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), nestedClass.Field1); + Assert.That(result, Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), nestedClass.Field2); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == nestedClass.Field1.NameField); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "Field3"); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), nestedClass.Field1); + Assert.That(result, Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), nestedClass.Field2); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == nestedClass.Field1.NameProp); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "Prop3"); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), nestedClass.Field1); + Assert.That(result, Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), nestedClass.Field2); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + } + + private void FieldSequenceTest(Session session) + { + var nestedClass = new NestedClass(); + nestedClass.InitContainers(nameof(NestedClassTestRunner.AccessInsideNestedClassTest)); + + //fields + var methodName = "FieldTest"; + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == nestedClass.Field1.BaseNameField); + var cachingKey = ComposeKey(nameof(NestedClass), methodName, "BaseField3"); + + var result = session.Query.Execute(cachingKey, (q) => query, nestedClass.Field1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query, nestedClass.Field2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == nestedClass.Field1.BaseNameProp); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "BaseProp3"); + + result = session.Query.Execute(cachingKey, (q) => query, nestedClass.Field1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query, nestedClass.Field2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == nestedClass.Field1.NameField); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "Field3"); + + result = session.Query.Execute(cachingKey, (q) => query, nestedClass.Field1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query, nestedClass.Field2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == nestedClass.Field1.NameProp); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "Prop3"); + + result = session.Query.Execute(cachingKey, (q) => query, nestedClass.Field1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query, nestedClass.Field2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + } + + private void FieldOrderedSequenceTest(Session session) + { + var nestedClass = new NestedClass(); + nestedClass.InitContainers(nameof(NestedClassTestRunner.AccessInsideNestedClassTest)); + + //fields + var methodName = "FieldTest"; + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == nestedClass.Field1.BaseNameField); + var cachingKey = ComposeKey(nameof(NestedClass), methodName, "BaseField3"); + + var result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), nestedClass.Field1); + Assert.That(result, Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), nestedClass.Field2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == nestedClass.Field1.BaseNameProp); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "BaseProp3"); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), nestedClass.Field1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), nestedClass.Field2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == nestedClass.Field1.NameField); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "Field3"); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), nestedClass.Field1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), nestedClass.Field2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == nestedClass.Field1.NameProp); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "Prop3"); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), nestedClass.Field1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), nestedClass.Field2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + } + + private void PropertyScalarTest(Session session) + { + var nestedClass = new NestedClass(); + nestedClass.InitContainers(nameof(NestedClassTestRunner.AccessInsideNestedClassTest)); + + //props + var methodName = "PropertyTest"; + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == nestedClass.Prop1.BaseNameField); + var cachingKey = ComposeKey(nameof(NestedClass), methodName, "BaseField4"); + + var result = session.Query.Execute(cachingKey, (q) => query.Count(), nestedClass.Prop1); + Assert.That(result, Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), nestedClass.Prop2); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == nestedClass.Prop1.BaseNameProp); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "BaseProp4"); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), nestedClass.Prop1); + Assert.That(result, Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), nestedClass.Prop2); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == nestedClass.Prop1.NameField); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "Field4"); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), nestedClass.Prop1); + Assert.That(result, Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), nestedClass.Prop2); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == nestedClass.Prop1.NameProp); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "Prop4"); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), nestedClass.Prop1); + Assert.That(result, Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), nestedClass.Prop2); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + private void PropertySequenceTest(Session session) + { + var nestedClass = new NestedClass(); + nestedClass.InitContainers(nameof(NestedClassTestRunner.AccessInsideNestedClassTest)); + + var methodName = "PropertyTest"; + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == nestedClass.Prop1.BaseNameField); + var cachingKey = ComposeKey(nameof(NestedClass), methodName, "BaseField4"); + + var result = session.Query.Execute(cachingKey, (q) => query, nestedClass.Prop1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query, nestedClass.Prop2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == nestedClass.Prop1.BaseNameProp); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "BaseProp4"); + + result = session.Query.Execute(cachingKey, (q) => query, nestedClass.Prop1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query, nestedClass.Prop2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == nestedClass.Prop1.NameField); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "Field4"); + + result = session.Query.Execute(cachingKey, (q) => query, nestedClass.Prop1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query, nestedClass.Prop2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == nestedClass.Prop1.NameProp); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "Prop4"); + + result = session.Query.Execute(cachingKey, (q) => query, nestedClass.Prop1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query, nestedClass.Prop2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + private void PropertyOrderedSequenceTest(Session session) + { + var nestedClass = new NestedClass(); + nestedClass.InitContainers(nameof(NestedClassTestRunner.AccessInsideNestedClassTest)); + + //props + var methodName = "PropertyTest"; + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == nestedClass.Prop1.BaseNameField); + var cachingKey = ComposeKey(nameof(NestedClass), methodName, "BaseField4"); + + var result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), nestedClass.Prop1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), nestedClass.Prop2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == nestedClass.Prop1.BaseNameProp); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "BaseProp4"); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), nestedClass.Prop1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), nestedClass.Prop2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == nestedClass.Prop1.NameField); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "Field4"); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), nestedClass.Prop1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), nestedClass.Prop2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == nestedClass.Prop1.NameProp); + cachingKey = ComposeKey(nameof(NestedClass), methodName, "Prop4"); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), nestedClass.Prop1); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), nestedClass.Prop2); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + } +} diff --git a/Orm/Xtensive.Orm.Tests/Storage/CustomClosureForCachingQueries/TestRunners.ParameterTestRunner.cs b/Orm/Xtensive.Orm.Tests/Storage/CustomClosureForCachingQueries/TestRunners.ParameterTestRunner.cs new file mode 100644 index 0000000000..9369b7fe9b --- /dev/null +++ b/Orm/Xtensive.Orm.Tests/Storage/CustomClosureForCachingQueries/TestRunners.ParameterTestRunner.cs @@ -0,0 +1,640 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NUnit.Framework; +using Xtensive.Orm.Tests.Storage.InlineQueriesCachingTestModel; + +namespace Xtensive.Orm.Tests.Storage.InlineQueriesCachingTestModel.TestRunners +{ + public class ParameterTestRunner : TestRunnerBase + { + private static readonly string thisClassName = nameof(ParameterTestRunner); + + protected override string ThisClassName => thisClassName; + + public void GeneralAccessScalar(Session session) + { + var thisMethodName = nameof(ParameterTestRunner.GeneralAccessScalar); + +#pragma warning disable IDE0018 // Inline variable declaration + ParameterContainer local1, local2, local3; + InitVariables(thisMethodName, out local1, out local2, out local3); +#pragma warning restore IDE0018 // Inline variable declaration + + GeneralAccessScalarInternal(session, thisMethodName, local1, local2, local3); + } + + public void GeneralAccessSequence(Session session) + { + var thisMethodName = nameof(ParameterTestRunner.GeneralAccessSequence); + +#pragma warning disable IDE0018 // Inline variable declaration + ParameterContainer local1, local2, local3; + InitVariables(thisMethodName, out local1, out local2, out local3); +#pragma warning restore IDE0018 // Inline variable declaration + + GeneralAccessScalarInternal(session, thisMethodName, local1, local2, local3); + } + + public void GeneralAccessOrderedSequence(Session session) + { + var thisMethodName = nameof(ParameterTestRunner.GeneralAccessOrderedSequence); + +#pragma warning disable IDE0018 // Inline variable declaration + ParameterContainer local1, local2, local3; + InitVariables(thisMethodName, out local1, out local2, out local3); +#pragma warning restore IDE0018 // Inline variable declaration + + GeneralAccessScalarInternal(session, thisMethodName, local1, local2, local3); + } + + public void AccessFromNestedMethodScalar(Session session) + { + var thisMethodName = nameof(ParameterTestRunner.AccessFromNestedMethodScalar); + +#pragma warning disable IDE0018 // Inline variable declaration + ParameterContainer local1, local2, local3; + InitVariables(thisMethodName, out local1, out local2, out local3); +#pragma warning restore IDE0018 // Inline variable declaration + + AccessFromNestedMethodScalarInternal(session, thisMethodName, local1, local2, local3); + } + + public void AccessFromNestedMethodSequence(Session session) + { + var thisMethodName = nameof(ParameterTestRunner.AccessFromNestedMethodSequence); + +#pragma warning disable IDE0018 // Inline variable declaration + ParameterContainer local1, local2, local3; + InitVariables(thisMethodName, out local1, out local2, out local3); +#pragma warning restore IDE0018 // Inline variable declaration + + AccessFromNestedMethodSequenceInternal(session, thisMethodName, local1, local2, local3); + } + + public void AccessFromNestedMethodOrderedSequence(Session session) + { + var thisMethodName = nameof(ParameterTestRunner.AccessFromNestedMethodOrderedSequence); + +#pragma warning disable IDE0018 // Inline variable declaration + ParameterContainer local1, local2, local3; + InitVariables(thisMethodName, out local1, out local2, out local3); +#pragma warning restore IDE0018 // Inline variable declaration + + AccessFromNestedMethodOrderedSequenceInternal(session, thisMethodName, local1, local2, local3); + } + + public void AccessFromLocalFuncScalar(Session session) + { + var thisMethodName = nameof(ParameterTestRunner.AccessFromLocalFuncScalar); + +#pragma warning disable IDE0018 // Inline variable declaration + ParameterContainer local1, local2, local3; + InitVariables(thisMethodName, out local1, out local2, out local3); +#pragma warning restore IDE0018 // Inline variable declaration + + AccessFromLocalFuncScalarInternal(session, thisMethodName, local1, local2, local3); + } + + public void AccessFromLocalFuncSequence(Session session) + { + var thisMethodName = nameof(ParameterTestRunner.AccessFromLocalFuncSequence); + +#pragma warning disable IDE0018 // Inline variable declaration + ParameterContainer local1, local2, local3; + InitVariables(thisMethodName, out local1, out local2, out local3); +#pragma warning restore IDE0018 // Inline variable declaration + + AccessFromLocalFuncSequenceInternal(session, thisMethodName, local1, local2, local3); + } + + public void AccessFromLocalFuncOrderedSequence(Session session) + { + var thisMethodName = nameof(ParameterTestRunner.AccessFromLocalFuncOrderedSequence); + +#pragma warning disable IDE0018 // Inline variable declaration + ParameterContainer local1, local2, local3; + InitVariables(thisMethodName, out local1, out local2, out local3); +#pragma warning restore IDE0018 // Inline variable declaration + + AccessFromLocalFuncOrderedSequenceInternal(session, thisMethodName, local1, local2, local3); + } + + private void GeneralAccessScalarInternal(Session session, string methodName, ParameterContainer parameter1, ParameterContainer parameter2, ParameterContainer parameter3) + { + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == parameter1.NameField); + var cachingKey = ComposeKey(ThisClassName, methodName, "Field"); + + var result = session.Query.Execute(cachingKey, (q) => query.Count(), parameter1); + Assert.That(result, Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.Count(), parameter2); + Assert.That(result, Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.Count(), parameter3); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == parameter1.NameProp); + cachingKey = ComposeKey(ThisClassName, methodName, "Prop"); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), parameter1); + Assert.That(result, Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.Count(), parameter2); + Assert.That(result, Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.Count(), parameter3); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == parameter1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, methodName, "BaseField"); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), parameter1); + Assert.That(result, Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.Count(), parameter2); + Assert.That(result, Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.Count(), parameter3); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == parameter1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, methodName, "BaseProp"); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), parameter1); + Assert.That(result, Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.Count(), parameter2); + Assert.That(result, Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.Count(), parameter3); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + private void GeneralAccessSequenceInternal(Session session, string methodName, ParameterContainer parameter1, ParameterContainer parameter2, ParameterContainer parameter3) + { + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == parameter1.NameField); + var cachingKey = ComposeKey(ThisClassName, methodName, "Field"); + + var result = session.Query.Execute(cachingKey, (q) => query, parameter1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query, parameter2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query, parameter3); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == parameter1.NameProp); + cachingKey = ComposeKey(ThisClassName, methodName, "Prop"); + + result = session.Query.Execute(cachingKey, (q) => query, parameter1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query, parameter2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query, parameter3); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == parameter1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, methodName, "BaseField"); + + result = session.Query.Execute(cachingKey, (q) => query, parameter1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query, parameter2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query, parameter3); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == parameter1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, methodName, "BaseProp"); + + result = session.Query.Execute(cachingKey, (q) => query, parameter1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query, parameter2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query, parameter3); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + private void GeneralAccessOrderedSequenceInternal(Session session, string methodName, ParameterContainer parameter1, ParameterContainer parameter2, ParameterContainer parameter3) + { + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == parameter1.NameField); + var cachingKey = ComposeKey(ThisClassName, methodName, "Field"); + + var result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), parameter1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), parameter2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), parameter3); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == parameter1.NameProp); + cachingKey = ComposeKey(ThisClassName, methodName, "Prop"); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), parameter1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), parameter2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), parameter3); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == parameter1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, methodName, "BaseField"); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), parameter1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), parameter2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), parameter3); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == parameter1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, methodName, "BaseProp"); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), parameter1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), parameter2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), parameter3); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + private void AccessFromNestedMethodScalarInternal(Session session, string methodName, ParameterContainer parameter1, ParameterContainer parameter2, ParameterContainer parameter3) + { + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == parameter1.NameField); + var cachingKey = ComposeKey(ThisClassName, methodName, "Field"); + + var result = Execute1(); + Assert.That(result, Is.EqualTo(1)); + result = Execute2(); + Assert.That(result, Is.EqualTo(1)); + result = Execute3(); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == parameter1.NameProp); + cachingKey = ComposeKey(ThisClassName, methodName, "Prop"); + + result = Execute1(); + Assert.That(result, Is.EqualTo(1)); + result = Execute2(); + Assert.That(result, Is.EqualTo(1)); + result = Execute3(); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == parameter1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, methodName, "BaseField"); + + result = Execute1(); + Assert.That(result, Is.EqualTo(1)); + result = Execute2(); + Assert.That(result, Is.EqualTo(1)); + result = Execute3(); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == parameter1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, methodName, "BaseProp"); + + result = Execute1(); + Assert.That(result, Is.EqualTo(1)); + result = Execute2(); + Assert.That(result, Is.EqualTo(1)); + result = Execute3(); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + + int Execute1() + { + return session.Query.Execute(cachingKey, (q) => query.Count(), parameter1); + } + int Execute2() + { + return session.Query.Execute(cachingKey, (q) => query.Count(), parameter2); + } + int Execute3() + { + return session.Query.Execute(cachingKey, (q) => query.Count(), parameter3); + } + } + + private void AccessFromNestedMethodSequenceInternal(Session session, string methodName, ParameterContainer parameter1, ParameterContainer parameter2, ParameterContainer parameter3) + { + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == parameter1.NameField); + var cachingKey = ComposeKey(ThisClassName, methodName, "Field"); + + var result = Execute1(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute2(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute3(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == parameter1.NameProp); + cachingKey = ComposeKey(ThisClassName, methodName, "Prop"); + + result = Execute1(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute2(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute3(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == parameter1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, methodName, "BaseField"); + + result = Execute1(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute2(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute3(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == parameter1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, methodName, "BaseProp"); + + result = Execute1(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute2(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute3(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + + IEnumerable Execute1() + { + return session.Query.Execute(cachingKey, (q) => query, parameter1); + } + IEnumerable Execute2() + { + return session.Query.Execute(cachingKey, (q) => query, parameter2); + } + IEnumerable Execute3() + { + return session.Query.Execute(cachingKey, (q) => query, parameter3); + } + } + + private void AccessFromNestedMethodOrderedSequenceInternal(Session session, string methodName, ParameterContainer parameter1, ParameterContainer parameter2, ParameterContainer parameter3) + { + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == parameter1.NameField); + var cachingKey = ComposeKey(ThisClassName, methodName, "Field"); + + var result = Execute1(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute2(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute3(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == parameter1.NameProp); + cachingKey = ComposeKey(ThisClassName, methodName, "Prop"); + + result = Execute1(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute2(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute3(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == parameter1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, methodName, "BaseField"); + + result = Execute1(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute2(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute3(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == parameter1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, methodName, "BaseProp"); + + result = Execute1(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute2(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute3(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + + IEnumerable Execute1() + { + return session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), parameter1); + } + IEnumerable Execute2() + { + return session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), parameter2); + } + IEnumerable Execute3() + { + return session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), parameter3); + } + } + + private void AccessFromLocalFuncScalarInternal(Session session, string methodName, ParameterContainer parameter1, ParameterContainer parameter2, ParameterContainer parameter3) + { + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == parameter1.NameField); + var cachingKey = ComposeKey(ThisClassName, methodName, "Field"); + +#pragma warning disable IDE0039 // Use local function + Func execute1 = () => session.Query.Execute(cachingKey, (q) => query.Count(), parameter1); + Func execute2 = () => session.Query.Execute(cachingKey, (q) => query.Count(), parameter2); + Func execute3 = () => session.Query.Execute(cachingKey, (q) => query.Count(), parameter3); +#pragma warning restore IDE0039 // Use local function + + var result = execute1.Invoke(); + Assert.That(result, Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result, Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == parameter1.NameProp); + cachingKey = ComposeKey(ThisClassName, methodName, "Prop"); + + result = execute1.Invoke(); + Assert.That(result, Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result, Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == parameter1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, methodName, "BaseField"); + + result = execute1.Invoke(); + Assert.That(result, Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result, Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == parameter1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, methodName, "BaseProp"); + + result = execute1.Invoke(); + Assert.That(result, Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result, Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + private void AccessFromLocalFuncSequenceInternal(Session session, string methodName, ParameterContainer parameter1, ParameterContainer parameter2, ParameterContainer parameter3) + { + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == parameter1.NameField); + var cachingKey = ComposeKey(ThisClassName, methodName, "Field"); + +#pragma warning disable IDE0039 // Use local function + Func> execute1 = () => session.Query.Execute(cachingKey, (q) => query, parameter1); + Func> execute2 = () => session.Query.Execute(cachingKey, (q) => query, parameter2); + Func> execute3 = () => session.Query.Execute(cachingKey, (q) => query, parameter3); +#pragma warning restore IDE0039 // Use local function + + var result = execute1.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == parameter1.NameProp); + cachingKey = ComposeKey(ThisClassName, methodName, "Prop"); + + result = execute1.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == parameter1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, methodName, "BaseField"); + + result = execute1.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == parameter1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, methodName, "BaseProp"); + + result = execute1.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + private void AccessFromLocalFuncOrderedSequenceInternal(Session session, string methodName, ParameterContainer parameter1, ParameterContainer parameter2, ParameterContainer parameter3) + { + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == parameter1.NameField); + var cachingKey = ComposeKey(ThisClassName, methodName, "Field"); + +#pragma warning disable IDE0039 // Use local function + Func> execute1 = () => session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), parameter1); + Func> execute2 = () => session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), parameter2); + Func> execute3 = () => session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), parameter3); +#pragma warning restore IDE0039 // Use local function + + var result = execute1.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == parameter1.NameProp); + cachingKey = ComposeKey(ThisClassName, methodName, "Prop"); + + result = execute1.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == parameter1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, methodName, "BaseField"); + + result = execute1.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == parameter1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, methodName, "BaseProp"); + + result = execute1.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + } +} diff --git a/Orm/Xtensive.Orm.Tests/Storage/CustomClosureForCachingQueries/TestRunners.StaticFieldTestRunner.cs b/Orm/Xtensive.Orm.Tests/Storage/CustomClosureForCachingQueries/TestRunners.StaticFieldTestRunner.cs new file mode 100644 index 0000000000..fba73823dc --- /dev/null +++ b/Orm/Xtensive.Orm.Tests/Storage/CustomClosureForCachingQueries/TestRunners.StaticFieldTestRunner.cs @@ -0,0 +1,731 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NUnit.Framework; +using Xtensive.Orm.Tests.Storage.InlineQueriesCachingTestModel; + +namespace Xtensive.Orm.Tests.Storage.InlineQueriesCachingTestModel.TestRunners +{ + public class StaticFieldTestRunner : TestRunnerBase + { + private readonly static string thisClassName = nameof(StaticFieldTestRunner); + + private static ParameterContainer field1; + private static ParameterContainer field2; + private static ParameterContainer field3; + + protected override string ThisClassName => thisClassName; + + public void GeneralAccessScalar(Session session) + { + var thisMethodName = nameof(StaticFieldTestRunner.GeneralAccessScalar); + + InitVariables(thisMethodName, out field1, out field2, out field3); + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == field1.NameField); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "Field"); + + var result = session.Query.Execute(cachingKey, (q) => query.Count(), field1); + Assert.That(result, Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.Count(), field2); + Assert.That(result, Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.Count(), field3); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.NameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "Prop"); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), field1); + Assert.That(result, Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.Count(), field2); + Assert.That(result, Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.Count(), field3); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseField"); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), field1); + Assert.That(result, Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.Count(), field2); + Assert.That(result, Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.Count(), field3); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), field1); + Assert.That(result, Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.Count(), field2); + Assert.That(result, Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.Count(), field3); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + public void GeneralAccessSequence(Session session) + { + var thisMethodName = nameof(StaticFieldTestRunner.GeneralAccessSequence); + + InitVariables(thisMethodName, out field1, out field2, out field3); + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == field1.NameField); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "Field"); + + var result = session.Query.Execute(cachingKey, (q) => query, field1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query, field2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query, field3); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.NameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "Prop"); + + result = session.Query.Execute(cachingKey, (q) => query, field1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query, field2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query, field3); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseField"); + + result = session.Query.Execute(cachingKey, (q) => query, field1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query, field2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query, field3); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + result = session.Query.Execute(cachingKey, (q) => query, field1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query, field2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query, field3); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + public void GeneralAccessOrderedSequence(Session session) + { + var thisMethodName = nameof(StaticFieldTestRunner.GeneralAccessOrderedSequence); + + InitVariables(thisMethodName, out field1, out field2, out field3); + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == field1.NameField); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "Field"); + + var result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), field1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), field2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), field3); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.NameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "Prop"); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), field1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), field2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), field3); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseField"); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), field1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), field2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), field3); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), field1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), field2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), field3); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + public void AccessFromNestedMethodScalar(Session session) + { + var thisMethodName = nameof(StaticFieldTestRunner.AccessFromNestedMethodScalar); + + InitVariables(thisMethodName, out field1, out field2, out field3); + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == field1.NameField); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "Field"); + + var result = Execute1(); + Assert.That(result, Is.EqualTo(1)); + result = Execute2(); + Assert.That(result, Is.EqualTo(1)); + result = Execute3(); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.NameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "Prop"); + + result = Execute1(); + Assert.That(result, Is.EqualTo(1)); + result = Execute2(); + Assert.That(result, Is.EqualTo(1)); + result = Execute3(); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseField"); + + result = Execute1(); + Assert.That(result, Is.EqualTo(1)); + result = Execute2(); + Assert.That(result, Is.EqualTo(1)); + result = Execute3(); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + result = Execute1(); + Assert.That(result, Is.EqualTo(1)); + result = Execute2(); + Assert.That(result, Is.EqualTo(1)); + result = Execute3(); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + + int Execute1() + { + return session.Query.Execute(cachingKey, (q) => query.Count(), field1); + } + int Execute2() + { + return session.Query.Execute(cachingKey, (q) => query.Count(), field2); + } + int Execute3() + { + return session.Query.Execute(cachingKey, (q) => query.Count(), field3); + } + } + + public void AccessFromNestedMethodSequence(Session session) + { + var thisMethodName = nameof(StaticFieldTestRunner.AccessFromNestedMethodSequence); + + InitVariables(thisMethodName, out field1, out field2, out field3); + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == field1.NameField); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "Field"); + + var result = Execute1(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute2(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute3(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.NameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "Prop"); + + result = Execute1(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute2(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute3(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseField"); + + result = Execute1(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute2(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute3(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + result = Execute1(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute2(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute3(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + + IEnumerable Execute1() + { + return session.Query.Execute(cachingKey, (q) => query, field1); + } + IEnumerable Execute2() + { + return session.Query.Execute(cachingKey, (q) => query, field2); + } + IEnumerable Execute3() + { + return session.Query.Execute(cachingKey, (q) => query, field3); + } + } + + public void AccessFromNestedMethodOrderedSequence(Session session) + { + var thisMethodName = nameof(StaticFieldTestRunner.AccessFromNestedMethodOrderedSequence); + + InitVariables(thisMethodName, out field1, out field2, out field3); + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == field1.NameField); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "Field"); + + var result = Execute1(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute2(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute3(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.NameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "Prop"); + + result = Execute1(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute2(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute3(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseField"); + + result = Execute1(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute2(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute3(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + result = Execute1(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute2(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute3(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + + IEnumerable Execute1() + { + return session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), field1); + } + IEnumerable Execute2() + { + return session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), field2); + } + IEnumerable Execute3() + { + return session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), field3); + } + } + + public void AccessFromLocalFuncScalar(Session session) + { + var thisMethodName = nameof(StaticFieldTestRunner.AccessFromLocalFuncScalar); + + InitVariables(thisMethodName, out field1, out field2, out field3); + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == field1.NameField); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "Field"); + +#pragma warning disable IDE0039 // Use local function + Func execute1 = () => session.Query.Execute(cachingKey, (q) => query.Count(), field1); + Func execute2 = () => session.Query.Execute(cachingKey, (q) => query.Count(), field2); + Func execute3 = () => session.Query.Execute(cachingKey, (q) => query.Count(), field3); +#pragma warning restore IDE0039 // Use local function + + var result = execute1.Invoke(); + Assert.That(result, Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result, Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.NameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "Prop"); + + result = execute1.Invoke(); + Assert.That(result, Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result, Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseField"); + + result = execute1.Invoke(); + Assert.That(result, Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result, Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + result = execute1.Invoke(); + Assert.That(result, Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result, Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + public void AccessFromLocalFuncSequence(Session session) + { + var thisMethodName = nameof(StaticFieldTestRunner.AccessFromLocalFuncSequence); + + InitVariables(thisMethodName, out field1, out field2, out field3); + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == field1.NameField); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "Field"); + +#pragma warning disable IDE0039 // Use local function + Func> execute1 = () => session.Query.Execute(cachingKey, (q) => query, field1); + Func> execute2 = () => session.Query.Execute(cachingKey, (q) => query, field2); + Func> execute3 = () => session.Query.Execute(cachingKey, (q) => query, field3); +#pragma warning restore IDE0039 // Use local function + + var result = execute1.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.NameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "Prop"); + + result = execute1.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseField"); + + result = execute1.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + result = execute1.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + public void AccessFromLocalFuncOrderedSequence(Session session) + { + var thisMethodName = nameof(StaticFieldTestRunner.AccessFromLocalFuncOrderedSequence); + + InitVariables(thisMethodName, out field1, out field2, out field3); + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == field1.NameField); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "Field"); + +#pragma warning disable IDE0039 // Use local function + Func> execute1 = () => session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), field1); + Func> execute2 = () => session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), field2); + Func> execute3 = () => session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), field3); +#pragma warning restore IDE0039 // Use local function + + var result = execute1.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.NameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "Prop"); + + result = execute1.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseField"); + + result = execute1.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == field1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + result = execute1.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + public void CacheAcrossMethodsScalar(Session session) + { + var thisMethodName = nameof(StaticPropertyTestRunner.CacheAcrossMethodsScalar); + + InitVariables(thisMethodName, out field1, out field2, out field3); + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var sharedQueryable = session.Query.All().Where(q => q.Name == field1.BaseNameProp); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + var result = ScalarMethod1(session, cachingKey, sharedQueryable); + Assert.That(result, Is.EqualTo(1)); + result = ScalarMethod2(session, cachingKey, sharedQueryable); + Assert.That(result, Is.EqualTo(1)); + result = ScalarMethod3(session, cachingKey, sharedQueryable); + Assert.That(result, Is.EqualTo(1)); + + var queryable1 = session.Query.All().Where(q => q.Name == field1.BaseNameProp); + var queryable2 = session.Query.All().Where(q => q.Name == field1.BaseNameProp); + var queryable3 = session.Query.All().Where(q => q.Name == field1.BaseNameProp); + + result = ScalarMethod1(session, cachingKey, queryable1); + Assert.That(result, Is.EqualTo(1)); + result = ScalarMethod1(session, cachingKey, queryable2); + Assert.That(result, Is.EqualTo(1)); + result = ScalarMethod1(session, cachingKey, queryable3); + Assert.That(result, Is.EqualTo(1)); + + result = ScalarMethod2(session, cachingKey, queryable1); + Assert.That(result, Is.EqualTo(1)); + result = ScalarMethod2(session, cachingKey, queryable2); + Assert.That(result, Is.EqualTo(1)); + result = ScalarMethod2(session, cachingKey, queryable3); + Assert.That(result, Is.EqualTo(1)); + + result = ScalarMethod3(session, cachingKey, queryable1); + Assert.That(result, Is.EqualTo(1)); + result = ScalarMethod3(session, cachingKey, queryable2); + Assert.That(result, Is.EqualTo(1)); + result = ScalarMethod3(session, cachingKey, queryable3); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + public void CacheAcrossMethodsSequence(Session session) + { + var thisMethodName = nameof(StaticPropertyTestRunner.CacheAcrossMethodsSequence); + + InitVariables(thisMethodName, out field1, out field2, out field3); + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var sharedQueryable = session.Query.All().Where(q => q.Name == field1.BaseNameProp); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + var result = SequenceMethod1(session, cachingKey, sharedQueryable); + Assert.That(result.Count(), Is.EqualTo(1)); + result = SequenceMethod2(session, cachingKey, sharedQueryable); + Assert.That(result.Count(), Is.EqualTo(1)); + result = SequenceMethod3(session, cachingKey, sharedQueryable); + Assert.That(result.Count(), Is.EqualTo(1)); + + var queryable1 = session.Query.All().Where(q => q.Name == field1.BaseNameProp); + var queryable2 = session.Query.All().Where(q => q.Name == field1.BaseNameProp); + var queryable3 = session.Query.All().Where(q => q.Name == field1.BaseNameProp); + + result = SequenceMethod1(session, cachingKey, queryable1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = SequenceMethod1(session, cachingKey, queryable2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = SequenceMethod1(session, cachingKey, queryable3); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = SequenceMethod2(session, cachingKey, queryable1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = SequenceMethod2(session, cachingKey, queryable2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = SequenceMethod2(session, cachingKey, queryable3); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = SequenceMethod3(session, cachingKey, queryable1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = SequenceMethod3(session, cachingKey, queryable2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = SequenceMethod3(session, cachingKey, queryable3); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + public void CacheAcrossMethodsOrderedSequence(Session session) + { + var thisMethodName = nameof(StaticPropertyTestRunner.CacheAcrossMethodsOrderedSequence); + + InitVariables(thisMethodName, out field1, out field2, out field3); + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var sharedQueryable = session.Query.All().Where(q => q.Name == field1.BaseNameProp); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + var result = OrderedSequenceMethod1(session, cachingKey, sharedQueryable); + Assert.That(result.Count(), Is.EqualTo(1)); + result = OrderedSequenceMethod2(session, cachingKey, sharedQueryable); + Assert.That(result.Count(), Is.EqualTo(1)); + result = OrderedSequenceMethod3(session, cachingKey, sharedQueryable); + Assert.That(result.Count(), Is.EqualTo(1)); + + var queryable1 = session.Query.All().Where(q => q.Name == field1.BaseNameProp); + var queryable2 = session.Query.All().Where(q => q.Name == field1.BaseNameProp); + var queryable3 = session.Query.All().Where(q => q.Name == field1.BaseNameProp); + + result = OrderedSequenceMethod1(session, cachingKey, queryable1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = OrderedSequenceMethod1(session, cachingKey, queryable2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = OrderedSequenceMethod1(session, cachingKey, queryable3); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = OrderedSequenceMethod2(session, cachingKey, queryable1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = OrderedSequenceMethod2(session, cachingKey, queryable2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = OrderedSequenceMethod2(session, cachingKey, queryable3); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = OrderedSequenceMethod3(session, cachingKey, queryable1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = OrderedSequenceMethod3(session, cachingKey, queryable2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = OrderedSequenceMethod3(session, cachingKey, queryable3); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + private int ScalarMethod1(Session session, string cachingKey, IQueryable query) => + session.Query.Execute(cachingKey, (q) => query.Count(), field1); + + private int ScalarMethod2(Session session, string cachingKey, IQueryable query) => + session.Query.Execute(cachingKey, (q) => query.Count(), field2); + + private int ScalarMethod3(Session session, string cachingKey, IQueryable query) => + session.Query.Execute(cachingKey, (q) => query.Count(), field3); + + private IEnumerable SequenceMethod1(Session session, string cachingKey, IQueryable query) => + session.Query.Execute(cachingKey, (q) => query, field1); + + private IEnumerable SequenceMethod2(Session session, string cachingKey, IQueryable query) => + session.Query.Execute(cachingKey, (q) => query, field2); + + private IEnumerable SequenceMethod3(Session session, string cachingKey, IQueryable query) => + session.Query.Execute(cachingKey, (q) => query, field3); + + private IEnumerable OrderedSequenceMethod1(Session session, string cachingKey, IQueryable query) => + session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), field1); + + private IEnumerable OrderedSequenceMethod2(Session session, string cachingKey, IQueryable query) => + session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), field2); + + private IEnumerable OrderedSequenceMethod3(Session session, string cachingKey, IQueryable query) => + session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), field3); + } +} diff --git a/Orm/Xtensive.Orm.Tests/Storage/CustomClosureForCachingQueries/TestRunners.StaticPropertyTestRunner.cs b/Orm/Xtensive.Orm.Tests/Storage/CustomClosureForCachingQueries/TestRunners.StaticPropertyTestRunner.cs new file mode 100644 index 0000000000..74d4ed79ff --- /dev/null +++ b/Orm/Xtensive.Orm.Tests/Storage/CustomClosureForCachingQueries/TestRunners.StaticPropertyTestRunner.cs @@ -0,0 +1,739 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NUnit.Framework; +using Xtensive.Orm.Tests.Storage.InlineQueriesCachingTestModel; + +namespace Xtensive.Orm.Tests.Storage.InlineQueriesCachingTestModel.TestRunners +{ + public class StaticPropertyTestRunner : TestRunnerBase + { + private readonly static string thisClassName = nameof(StaticPropertyTestRunner); + + private static ParameterContainer Prop1 { get; set; } + private static ParameterContainer Prop2 { get; set; } + private static ParameterContainer Prop3 { get; set; } + + protected override string ThisClassName => thisClassName; + + public void GeneralAccessScalar(Session session) + { + var thisMethodName = nameof(StaticPropertyTestRunner.GeneralAccessScalar); + + InitProperties(thisMethodName); + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == Prop1.NameField); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "Field"); + + var result = session.Query.Execute(cachingKey, (q) => query.Count(), Prop1); + Assert.That(result, Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.Count(), Prop2); + Assert.That(result, Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.Count(), Prop3); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.NameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "Prop"); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), Prop1); + Assert.That(result, Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.Count(), Prop2); + Assert.That(result, Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.Count(), Prop3); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseField"); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), Prop1); + Assert.That(result, Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.Count(), Prop2); + Assert.That(result, Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.Count(), Prop3); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + result = session.Query.Execute(cachingKey, (q) => query.Count(), Prop1); + Assert.That(result, Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.Count(), Prop2); + Assert.That(result, Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.Count(), Prop3); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + public void GeneralAccessSequence(Session session) + { + var thisMethodName = nameof(StaticPropertyTestRunner.GeneralAccessSequence); + + InitProperties(thisMethodName); + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == Prop1.NameField); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "Field"); + + var result = session.Query.Execute(cachingKey, (q) => query, Prop1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query, Prop2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query, Prop3); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.NameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "Prop"); + + result = session.Query.Execute(cachingKey, (q) => query, Prop1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query, Prop2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query, Prop3); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseField"); + + result = session.Query.Execute(cachingKey, (q) => query, Prop1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query, Prop2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query, Prop3); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + result = session.Query.Execute(cachingKey, (q) => query, Prop1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query, Prop2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query, Prop3); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + public void GeneralAccessOrderedSequence(Session session) + { + var thisMethodName = nameof(StaticPropertyTestRunner.GeneralAccessOrderedSequence); + + InitProperties(thisMethodName); + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == Prop1.NameField); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "Field"); + + var result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), Prop1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), Prop2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), Prop3); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.NameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "Prop"); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), Prop1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), Prop2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), Prop3); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseField"); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), Prop1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), Prop2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), Prop3); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), Prop1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), Prop2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), Prop3); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + public void AccessFromNestedMethodScalar(Session session) + { + var thisMethodName = nameof(StaticPropertyTestRunner.AccessFromNestedMethodScalar); + + InitProperties(thisMethodName); + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == Prop1.NameField); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "Field"); + + var result = Execute1(); + Assert.That(result, Is.EqualTo(1)); + result = Execute2(); + Assert.That(result, Is.EqualTo(1)); + result = Execute3(); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.NameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "Prop"); + + result = Execute1(); + Assert.That(result, Is.EqualTo(1)); + result = Execute2(); + Assert.That(result, Is.EqualTo(1)); + result = Execute3(); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseField"); + + result = Execute1(); + Assert.That(result, Is.EqualTo(1)); + result = Execute2(); + Assert.That(result, Is.EqualTo(1)); + result = Execute3(); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + result = Execute1(); + Assert.That(result, Is.EqualTo(1)); + result = Execute2(); + Assert.That(result, Is.EqualTo(1)); + result = Execute3(); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + + int Execute1() + { + return session.Query.Execute(cachingKey, (q) => query.Count(), Prop1); + } + int Execute2() + { + return session.Query.Execute(cachingKey, (q) => query.Count(), Prop2); + } + int Execute3() + { + return session.Query.Execute(cachingKey, (q) => query.Count(), Prop3); + } + } + + public void AccessFromNestedMethodSequence(Session session) + { + var thisMethodName = nameof(StaticPropertyTestRunner.AccessFromNestedMethodSequence); + + InitProperties(thisMethodName); + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == Prop1.NameField); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "Field"); + + var result = Execute1(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute2(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute3(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.NameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "Prop"); + + result = Execute1(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute2(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute3(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseField"); + + result = Execute1(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute2(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute3(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + result = Execute1(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute2(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute3(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + + IEnumerable Execute1() + { + return session.Query.Execute(cachingKey, (q) => query, Prop1); + } + IEnumerable Execute2() + { + return session.Query.Execute(cachingKey, (q) => query, Prop2); + } + IEnumerable Execute3() + { + return session.Query.Execute(cachingKey, (q) => query, Prop3); + } + } + + public void AccessFromNestedMethodOrderedSequence(Session session) + { + var thisMethodName = nameof(StaticPropertyTestRunner.AccessFromNestedMethodOrderedSequence); + + InitProperties(thisMethodName); + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == Prop1.NameField); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "Field"); + + var result = Execute1(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute2(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute3(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.NameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "Prop"); + + result = Execute1(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute2(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute3(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseField"); + + result = Execute1(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute2(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute3(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + result = Execute1(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute2(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = Execute3(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + + IEnumerable Execute1() + { + return session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), Prop1); + } + IEnumerable Execute2() + { + return session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), Prop2); + } + IEnumerable Execute3() + { + return session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), Prop3); + } + } + + public void AccessFromLocalFuncScalar(Session session) + { + var thisMethodName = nameof(StaticPropertyTestRunner.AccessFromLocalFuncScalar); + + InitProperties(thisMethodName); + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == Prop1.NameField); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "Field"); + +#pragma warning disable IDE0039 // Use local function + Func execute1 = () => session.Query.Execute(cachingKey, (q) => query.Count(), Prop1); + Func execute2 = () => session.Query.Execute(cachingKey, (q) => query.Count(), Prop2); + Func execute3 = () => session.Query.Execute(cachingKey, (q) => query.Count(), Prop3); +#pragma warning restore IDE0039 // Use local function + + var result = execute1.Invoke(); + Assert.That(result, Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result, Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.NameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "Prop"); + + result = execute1.Invoke(); + Assert.That(result, Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result, Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseField"); + + result = execute1.Invoke(); + Assert.That(result, Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result, Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + result = execute1.Invoke(); + Assert.That(result, Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result, Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + public void AccessFromLocalFuncSequence(Session session) + { + var thisMethodName = nameof(StaticPropertyTestRunner.AccessFromLocalFuncSequence); + + InitProperties(thisMethodName); + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == Prop1.NameField); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "Field"); + +#pragma warning disable IDE0039 // Use local function + Func> execute1 = () => session.Query.Execute(cachingKey, (q) => query, Prop1); + Func> execute2 = () => session.Query.Execute(cachingKey, (q) => query, Prop2); + Func> execute3 = () => session.Query.Execute(cachingKey, (q) => query, Prop3); +#pragma warning restore IDE0039 // Use local function + + var result = execute1.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.NameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "Prop"); + + result = execute1.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseField"); + + result = execute1.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + result = execute1.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + public void AccessFromLocalFuncOrderedSequence(Session session) + { + var thisMethodName = nameof(StaticPropertyTestRunner.AccessFromLocalFuncOrderedSequence); + + InitProperties(thisMethodName); + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var query = session.Query.All().Where(q => q.Name == Prop1.NameField); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "Field"); + +#pragma warning disable IDE0039 // Use local function + Func> execute1 = () => session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), Prop1); + Func> execute2 = () => session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), Prop2); + Func> execute3 = () => session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), Prop3); +#pragma warning restore IDE0039 // Use local function + + var result = execute1.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.NameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "Prop"); + + result = execute1.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.BaseNameField); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseField"); + + result = execute1.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + currentQueryCountInCache++; + + query = session.Query.All().Where(q => q.Name == Prop1.BaseNameProp); + cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + result = execute1.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute2.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + result = execute3.Invoke(); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + public void CacheAcrossMethodsScalar(Session session) + { + var thisMethodName = nameof(StaticPropertyTestRunner.CacheAcrossMethodsScalar); + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var sharedQueryable = session.Query.All().Where(q => q.Name == Prop1.BaseNameProp); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + var result = ScalarMethod1(session, cachingKey, sharedQueryable); + Assert.That(result, Is.EqualTo(1)); + result = ScalarMethod2(session, cachingKey, sharedQueryable); + Assert.That(result, Is.EqualTo(1)); + result = ScalarMethod3(session, cachingKey, sharedQueryable); + Assert.That(result, Is.EqualTo(1)); + + var queryable1 = session.Query.All().Where(q => q.Name == Prop1.BaseNameProp); + var queryable2 = session.Query.All().Where(q => q.Name == Prop1.BaseNameProp); + var queryable3 = session.Query.All().Where(q => q.Name == Prop1.BaseNameProp); + + result = ScalarMethod1(session, cachingKey, queryable1); + Assert.That(result, Is.EqualTo(1)); + result = ScalarMethod1(session, cachingKey, queryable2); + Assert.That(result, Is.EqualTo(1)); + result = ScalarMethod1(session, cachingKey, queryable3); + Assert.That(result, Is.EqualTo(1)); + + result = ScalarMethod2(session, cachingKey, queryable1); + Assert.That(result, Is.EqualTo(1)); + result = ScalarMethod2(session, cachingKey, queryable2); + Assert.That(result, Is.EqualTo(1)); + result = ScalarMethod2(session, cachingKey, queryable3); + Assert.That(result, Is.EqualTo(1)); + + result = ScalarMethod3(session, cachingKey, queryable1); + Assert.That(result, Is.EqualTo(1)); + result = ScalarMethod3(session, cachingKey, queryable2); + Assert.That(result, Is.EqualTo(1)); + result = ScalarMethod3(session, cachingKey, queryable3); + Assert.That(result, Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + public void CacheAcrossMethodsSequence(Session session) + { + var thisMethodName = nameof(StaticPropertyTestRunner.CacheAcrossMethodsSequence); + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var sharedQueryable = session.Query.All().Where(q => q.Name == Prop1.BaseNameProp); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + var result = SequenceMethod1(session, cachingKey, sharedQueryable); + Assert.That(result.Count(), Is.EqualTo(1)); + result = SequenceMethod2(session, cachingKey, sharedQueryable); + Assert.That(result.Count(), Is.EqualTo(1)); + result = SequenceMethod3(session, cachingKey, sharedQueryable); + Assert.That(result.Count(), Is.EqualTo(1)); + + var queryable1 = session.Query.All().Where(q => q.Name == Prop1.BaseNameProp); + var queryable2 = session.Query.All().Where(q => q.Name == Prop1.BaseNameProp); + var queryable3 = session.Query.All().Where(q => q.Name == Prop1.BaseNameProp); + + result = SequenceMethod1(session, cachingKey, queryable1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = SequenceMethod1(session, cachingKey, queryable2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = SequenceMethod1(session, cachingKey, queryable3); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = SequenceMethod2(session, cachingKey, queryable1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = SequenceMethod2(session, cachingKey, queryable2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = SequenceMethod2(session, cachingKey, queryable3); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = SequenceMethod3(session, cachingKey, queryable1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = SequenceMethod3(session, cachingKey, queryable2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = SequenceMethod3(session, cachingKey, queryable3); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + public void CacheAcrossMethodsOrderedSequence(Session session) + { + var thisMethodName = nameof(StaticPropertyTestRunner.CacheAcrossMethodsOrderedSequence); + + var currentQueryCountInCache = session.Domain.QueryCache.Count; + var sharedQueryable = session.Query.All().Where(q => q.Name == Prop1.BaseNameProp); + var cachingKey = ComposeKey(ThisClassName, thisMethodName, "BaseProp"); + + var result = OrderedSequenceMethod1(session, cachingKey, sharedQueryable); + Assert.That(result.Count(), Is.EqualTo(1)); + result = OrderedSequenceMethod2(session, cachingKey, sharedQueryable); + Assert.That(result.Count(), Is.EqualTo(1)); + result = OrderedSequenceMethod3(session, cachingKey, sharedQueryable); + Assert.That(result.Count(), Is.EqualTo(1)); + + var queryable1 = session.Query.All().Where(q => q.Name == Prop1.BaseNameProp); + var queryable2 = session.Query.All().Where(q => q.Name == Prop1.BaseNameProp); + var queryable3 = session.Query.All().Where(q => q.Name == Prop1.BaseNameProp); + + result = OrderedSequenceMethod1(session, cachingKey, queryable1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = OrderedSequenceMethod1(session, cachingKey, queryable2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = OrderedSequenceMethod1(session, cachingKey, queryable3); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = OrderedSequenceMethod2(session, cachingKey, queryable1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = OrderedSequenceMethod2(session, cachingKey, queryable2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = OrderedSequenceMethod2(session, cachingKey, queryable3); + Assert.That(result.Count(), Is.EqualTo(1)); + + result = OrderedSequenceMethod3(session, cachingKey, queryable1); + Assert.That(result.Count(), Is.EqualTo(1)); + result = OrderedSequenceMethod3(session, cachingKey, queryable2); + Assert.That(result.Count(), Is.EqualTo(1)); + result = OrderedSequenceMethod3(session, cachingKey, queryable3); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(session.Domain.QueryCache.Count, Is.EqualTo(currentQueryCountInCache + 1)); + } + + private int ScalarMethod1(Session session, string cachingKey, IQueryable query) => + session.Query.Execute(cachingKey, (q) => query.Count(), Prop1); + private int ScalarMethod2(Session session, string cachingKey, IQueryable query) => + session.Query.Execute(cachingKey, (q) => query.Count(), Prop2); + private int ScalarMethod3(Session session, string cachingKey, IQueryable query) => + session.Query.Execute(cachingKey, (q) => query.Count(), Prop3); + private IEnumerable SequenceMethod1(Session session, string cachingKey, IQueryable query) => + session.Query.Execute(cachingKey, (q) => query, Prop1); + private IEnumerable SequenceMethod2(Session session, string cachingKey, IQueryable query) => + session.Query.Execute(cachingKey, (q) => query, Prop2); + private IEnumerable SequenceMethod3(Session session, string cachingKey, IQueryable query) => + session.Query.Execute(cachingKey, (q) => query, Prop3); + private IEnumerable OrderedSequenceMethod1(Session session, string cachingKey, IQueryable query) => + session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), Prop1); + private IEnumerable OrderedSequenceMethod2(Session session, string cachingKey, IQueryable query) => + session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), Prop2); + private IEnumerable OrderedSequenceMethod3(Session session, string cachingKey, IQueryable query) => + session.Query.Execute(cachingKey, (q) => query.OrderBy(e => e.Id), Prop3); + + private void InitProperties(string methodName) + { + Prop1 = new ParameterContainer() { + BaseNameField = ThisClassName + methodName + "BaseField1", + BaseNameProp = ThisClassName + methodName + "BaseProp1", + NameField = ThisClassName + methodName + "Field1", + NameProp = ThisClassName + methodName + "Prop1", + }; + Prop2 = new ParameterContainer() { + BaseNameField = ThisClassName + methodName + "BaseField2", + BaseNameProp = ThisClassName + methodName + "BaseProp2", + NameField = ThisClassName + methodName + "Field2", + NameProp = ThisClassName + methodName + "Prop2", + }; + Prop3 = new ParameterContainer() { + BaseNameField = ThisClassName + methodName + "BaseField3", + BaseNameProp = ThisClassName + methodName + "BaseProp3", + NameField = ThisClassName + methodName + "Field3", + NameProp = ThisClassName + methodName + "Prop3", + }; + } + } +} diff --git a/Orm/Xtensive.Orm.Tests/Storage/CustomClosureForCachingQueries/TestRunners.cs b/Orm/Xtensive.Orm.Tests/Storage/CustomClosureForCachingQueries/TestRunners.cs new file mode 100644 index 0000000000..06ff5711e9 --- /dev/null +++ b/Orm/Xtensive.Orm.Tests/Storage/CustomClosureForCachingQueries/TestRunners.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NUnit.Framework; +using Xtensive.Orm.Tests.Storage.InlineQueriesCachingTestModel; + +namespace Xtensive.Orm.Tests.Storage.InlineQueriesCachingTestModel.TestRunners +{ + public abstract class TestRunnerBase + { + protected abstract string ThisClassName { get; } + + protected static string ComposeKey(string s1, string s2, string s3) + { + return s1 + s2 + s3; + } + + protected void InitVariables(string methodName, out ParameterContainer var1, out ParameterContainer var2, out ParameterContainer var3) + { + var1 = new ParameterContainer() { + BaseNameField = ThisClassName + methodName + "BaseField1", + BaseNameProp = ThisClassName + methodName + "BaseProp1", + NameField = ThisClassName + methodName + "Field1", + NameProp = ThisClassName + methodName + "Prop1", + }; + var2 = new ParameterContainer() { + BaseNameField = ThisClassName + methodName + "BaseField2", + BaseNameProp = ThisClassName + methodName + "BaseProp2", + NameField = ThisClassName + methodName + "Field2", + NameProp = ThisClassName + methodName + "Prop2", + }; + var3 = new ParameterContainer() { + BaseNameField = ThisClassName + methodName + "BaseField3", + BaseNameProp = ThisClassName + methodName + "BaseProp3", + NameField = ThisClassName + methodName + "Field3", + NameProp = ThisClassName + methodName + "Prop3", + }; + } + } +}