diff --git a/Orm/Xtensive.Orm/Orm/Domain.cs b/Orm/Xtensive.Orm/Orm/Domain.cs index 93d1845ee..7480800d7 100644 --- a/Orm/Xtensive.Orm/Orm/Domain.cs +++ b/Orm/Xtensive.Orm/Orm/Domain.cs @@ -4,12 +4,8 @@ // Created by: Dmitri Maximov // Created: 2007.08.03 -using System; using System.Collections.Concurrent; -using System.Collections.Generic; using System.Runtime.ExceptionServices; -using System.Threading; -using System.Threading.Tasks; using JetBrains.Annotations; using Xtensive.Caching; using Xtensive.Collections; @@ -132,8 +128,6 @@ public static Domain Demand() internal FastConcurrentLruCache QueryCache { get; } - internal ConcurrentDictionary RootCallExpressionsCache { get; } = new(); - /// /// Caches uncompiled queries used by to fetch certain entities. /// diff --git a/Orm/Xtensive.Orm/Orm/Linq/QueryHelper.cs b/Orm/Xtensive.Orm/Orm/Linq/QueryHelper.cs index e03e336d3..f1395a5a7 100644 --- a/Orm/Xtensive.Orm/Orm/Linq/QueryHelper.cs +++ b/Orm/Xtensive.Orm/Orm/Linq/QueryHelper.cs @@ -4,10 +4,7 @@ // Created by: Denis Krjuchkov // Created: 2009.04.02 -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; +using System.Collections.Concurrent; using System.Linq.Expressions; using System.Reflection; using Xtensive.Core; @@ -66,10 +63,10 @@ public static Expression> BuildFilterLambda(int startIndex, IR return FastExpression.Lambda>(filterExpression, TupleParameters); } - private static Expression CreateEntityQuery(Type elementType, Domain domain) - { - return domain.RootCallExpressionsCache.GetOrAdd(elementType, (t) => Expression.Call(null, WellKnownMembers.Query.All.MakeGenericMethod(elementType))); - } + private static readonly ConcurrentDictionary RootCallExpressionsCache = new(); + + internal static Expression CreateEntityQuery(Type elementType) => + RootCallExpressionsCache.GetOrAdd(elementType, static t => Expression.Call(null, WellKnownMembers.Query.All.MakeGenericMethod(t))); public static bool IsDirectEntitySetQuery(Expression entitySet) { @@ -134,7 +131,7 @@ public static Expression CreateEntitySetQuery(Expression ownerEntity, FieldInfo ); return Expression.Call( WellKnownMembers.Queryable.Where.CachedMakeGenericMethod(elementType), - CreateEntityQuery(elementType, domain), + CreateEntityQuery(elementType), FastExpression.Lambda(whereExpression, whereParameter) ); } @@ -159,7 +156,7 @@ public static Expression CreateEntitySetQuery(Expression ownerEntity, FieldInfo var outerQuery = Expression.Call( WellKnownMembers.Queryable.Where.CachedMakeGenericMethod(connectorType), - CreateEntityQuery(connectorType, domain), + CreateEntityQuery(connectorType), FastExpression.Lambda(filterExpression, filterParameter) ); @@ -171,7 +168,7 @@ public static Expression CreateEntitySetQuery(Expression ownerEntity, FieldInfo var innerSelector = FastExpression.Lambda(innerSelectorParameter, innerSelectorParameter); var resultSelector = FastExpression.Lambda(innerSelectorParameter, outerSelectorParameter, innerSelectorParameter); - var innerQuery = CreateEntityQuery(elementType, domain); + var innerQuery = CreateEntityQuery(elementType); var joinMethodInfo = WellKnownMembers.Queryable.Join .MakeGenericMethod(new[] { connectorType, diff --git a/Orm/Xtensive.Orm/Orm/QueryEndpoint.cs b/Orm/Xtensive.Orm/Orm/QueryEndpoint.cs index b647d9d40..4f2ed5251 100644 --- a/Orm/Xtensive.Orm/Orm/QueryEndpoint.cs +++ b/Orm/Xtensive.Orm/Orm/QueryEndpoint.cs @@ -2,19 +2,13 @@ // This code is distributed under MIT license terms. // See the License.txt file in the project root for more information. -using System; -using System.Collections.Generic; -using System.Linq; using System.Linq.Expressions; using System.Reflection; -using System.Threading; -using System.Threading.Tasks; using JetBrains.Annotations; using Xtensive.Core; using Xtensive.Orm.FullTextSearchCondition.Interfaces; using Xtensive.Orm.FullTextSearchCondition.Nodes; using Xtensive.Orm.Internals; -using Xtensive.Orm.Internals.Prefetch; using Xtensive.Orm.Linq; using Xtensive.Reflection; using Tuple = Xtensive.Tuples.Tuple; @@ -51,7 +45,13 @@ public bool Equals(QueryEndpoint other) => public override int GetHashCode() => HashCode.Combine(Provider, RootBuilder); - /// + private static class Traits + { + public static readonly MethodCallExpression RootCallExpression = + Expression.Call(null, WellKnownMembers.Query.All.MakeGenericMethod(typeof(T))); + } + + /// /// The "starting point" for any LINQ query - /// a enumerating all the instances /// of type . @@ -61,11 +61,10 @@ public bool Equals(QueryEndpoint other) => /// An enumerating all the instances /// of type . /// - public IQueryable All() - where T : class, IEntity - { - return Provider.CreateQuery(BuildRootExpression(typeof(T))); - } + public IQueryable All() where T : class, IEntity => + Provider.CreateQuery(RootBuilder != null + ? RootBuilder.BuildRootExpression(typeof(T)) + : Traits.RootCallExpression); /// /// The "starting point" for dynamic LINQ query - @@ -77,10 +76,11 @@ public IQueryable All() /// An enumerating all the instances /// of type . /// - public IQueryable All(Type elementType) - { - return ((IQueryProvider) Provider).CreateQuery(BuildRootExpression(elementType)); - } + public IQueryable All(Type elementType) => + ((IQueryProvider) Provider).CreateQuery(RootBuilder != null + ? RootBuilder.BuildRootExpression(elementType) + : QueryHelper.CreateEntityQuery(elementType) + ); #region Full-text related @@ -970,13 +970,6 @@ private Key GetKeyByValues(ReadOnlySpan keyValues) return Key.Create(session.Domain, session.StorageNodeId, session.Domain.Model.Types[typeof(T)], TypeReferenceAccuracy.BaseType, keyValues); } - private Expression BuildRootExpression(Type elementType) - { - return RootBuilder!=null - ? RootBuilder.BuildRootExpression(elementType) - : Session.Domain.RootCallExpressionsCache.GetOrAdd(elementType, (t) => Expression.Call(null, WellKnownMembers.Query.All.MakeGenericMethod(t))); - } - private static void ThrowKeyNotFoundException(Key key) => throw new KeyNotFoundException(String.Format(Strings.EntityWithKeyXDoesNotExist, key)); @@ -987,7 +980,6 @@ private static void ThrowKeyNotFoundException(Key key) => internal QueryEndpoint(QueryProvider provider) { - ArgumentNullException.ThrowIfNull(provider); Provider = provider; }