diff --git a/Orm/Xtensive.Orm/Orm/Attributes/KeyGeneratorKind.cs b/Orm/Xtensive.Orm/Orm/Attributes/KeyGeneratorKind.cs index cfc479fc5..a7a846ff0 100644 --- a/Orm/Xtensive.Orm/Orm/Attributes/KeyGeneratorKind.cs +++ b/Orm/Xtensive.Orm/Orm/Attributes/KeyGeneratorKind.cs @@ -9,7 +9,7 @@ namespace Xtensive.Orm /// /// Specifies key generator type to use for a particular hierarchy. /// - public enum KeyGeneratorKind + public enum KeyGeneratorKind : byte { /// /// No key generator is provided for hierarchy. @@ -35,4 +35,4 @@ public enum KeyGeneratorKind /// Custom = 2 } -} \ No newline at end of file +} diff --git a/Orm/Xtensive.Orm/Orm/Domain.cs b/Orm/Xtensive.Orm/Orm/Domain.cs index b6a68acd8..fda240a5f 100644 --- a/Orm/Xtensive.Orm/Orm/Domain.cs +++ b/Orm/Xtensive.Orm/Orm/Domain.cs @@ -23,6 +23,7 @@ using Xtensive.Orm.Logging; using Xtensive.Orm.Model; using Xtensive.Orm.Providers; +using Xtensive.Orm.Rse.Providers; using Xtensive.Orm.Upgrade; using Xtensive.Sql; using Xtensive.Sql.Info; @@ -134,6 +135,21 @@ public static Domain Demand() internal ConcurrentDictionary RootCallExpressionsCache { get; } = new(); + /// + /// Caches uncompiled queries used by to fetch certain entities. + /// + internal ConcurrentDictionary EntityFetchQueryCache { get; } = new(); + + /// + /// Caches uncompiled queries used by to fetch content. + /// + internal ConcurrentDictionary EntitySetFetchQueryCache { get; } = new(); + + /// + /// Caches queries that get references to entities for certain association. + /// + internal ConcurrentDictionary)> RefsToEntityQueryCache { get; } = new(); + internal object UpgradeContextCookie { get; private set; } internal SqlConnection SingleConnection { get; private set; } diff --git a/Orm/Xtensive.Orm/Orm/DomainBound.cs b/Orm/Xtensive.Orm/Orm/DomainBound.cs index 221bc66f2..2215ff6ef 100644 --- a/Orm/Xtensive.Orm/Orm/DomainBound.cs +++ b/Orm/Xtensive.Orm/Orm/DomainBound.cs @@ -4,60 +4,47 @@ // Created by: Dmitri Maximov // Created: 2007.08.10 -using System; using Xtensive.Core; -using Xtensive.IoC; -using Xtensive.Orm; -namespace Xtensive.Orm +namespace Xtensive.Orm; + +/// +/// Base class for all objects that are bound to the instance. +/// +public abstract class DomainBound: IContextBound { /// - /// Base class for all objects that are bound to the instance. + /// Gets to which current instance is bound. + /// + public Domain Domain { get; internal set; } + + #region IContextBound Members + + /// + Domain IContextBound.Context => Domain; + + #endregion + + + // Constructors + + /// + /// Initializes a new instance of this class. + /// + protected DomainBound() + { + } + + /// + /// Initializes a new instance of this class. /// - public abstract class DomainBound: IContextBound + /// , to which current instance + /// is bound. + /// is . + protected DomainBound(Domain domain) { - private Domain domain; - - /// - /// Gets to which current instance is bound. - /// - public Domain Domain - { - get { return domain; } - internal set { domain = value; } - } - - #region IContextBound Members - - /// - Domain IContextBound.Context - { - get { return domain; } - } - - #endregion - - - // Constructors - - /// - /// Initializes a new instance of this class. - /// - protected DomainBound() - { - } - - /// - /// Initializes a new instance of this class. - /// - /// , to which current instance - /// is bound. - /// is . - protected DomainBound(Domain domain) - { - ArgumentNullException.ThrowIfNull(domain); - this.domain = domain; - } + ArgumentNullException.ThrowIfNull(domain); + Domain = domain; } -} \ No newline at end of file +} diff --git a/Orm/Xtensive.Orm/Orm/Internals/EntitySetTypeState.cs b/Orm/Xtensive.Orm/Orm/Internals/EntitySetTypeState.cs index 29c75b99f..b52686a65 100644 --- a/Orm/Xtensive.Orm/Orm/Internals/EntitySetTypeState.cs +++ b/Orm/Xtensive.Orm/Orm/Internals/EntitySetTypeState.cs @@ -4,34 +4,16 @@ // Created by: Alexander Nikolaev // Created: 2009.08.04 -using System; -using Xtensive.Tuples; -using Xtensive.Orm.Providers; using Xtensive.Orm.Rse.Providers; using Tuple = Xtensive.Tuples.Tuple; using Xtensive.Tuples.Transform; -using Xtensive.Orm.Rse; -namespace Xtensive.Orm.Internals -{ - [Serializable] - internal sealed class EntitySetTypeState - { - public readonly ExecutableProvider SeekProvider; +namespace Xtensive.Orm.Internals; - public readonly MapTransform SeekTransform; - - public readonly Func ItemCtor; - - public readonly Func ItemCountQuery; - - public EntitySetTypeState(ExecutableProvider seekProvider, MapTransform seekTransform, - Func itemCtor, Func itemCountQuery) - { - SeekProvider = seekProvider; - SeekTransform = seekTransform; - ItemCtor = itemCtor; - ItemCountQuery = itemCountQuery; - } - } -} \ No newline at end of file +[Serializable] +internal record EntitySetTypeState( + ExecutableProvider SeekProvider, + MapTransform SeekTransform, + Func ItemCtor, + Func ItemCountQuery +); diff --git a/Orm/Xtensive.Orm/Orm/Internals/Prefetch/EntityGroupTask.cs b/Orm/Xtensive.Orm/Orm/Internals/Prefetch/EntityGroupTask.cs index b2d4e33ab..45fa7a7d0 100644 --- a/Orm/Xtensive.Orm/Orm/Internals/Prefetch/EntityGroupTask.cs +++ b/Orm/Xtensive.Orm/Orm/Internals/Prefetch/EntityGroupTask.cs @@ -4,9 +4,6 @@ // Created by: Alexander Nikolaev // Created: 2009.10.20 -using System; -using System.Collections.Generic; -using System.Linq; using Xtensive.Collections; using Xtensive.Core; using Xtensive.Orm.Model; @@ -33,11 +30,17 @@ public override bool Equals(object obj) => // Constructors - public RecordSetCacheKey(IReadOnlyList columnIndexes, TypeInfo type, int cachedHashCode) + public RecordSetCacheKey(IReadOnlyList columnIndexes, TypeInfo type) { ColumnIndexes = columnIndexes; Type = type; - this.cachedHashCode = cachedHashCode; + + HashCode hashCode = new(); + foreach (var columnIndex in columnIndexes) { + hashCode.Add(columnIndex); + } + hashCode.Add(type); + cachedHashCode = hashCode.ToHashCode(); } } @@ -125,7 +128,7 @@ private QueryTask CreateQueryTask(List currentKeySet) var parameterContext = new ParameterContext(); parameterContext.SetValue(includeParameter, currentKeySet); var session = manager.Owner.Session; - Provider = session.StorageNode.EntityFetchQueryCache.GetOrAdd(cacheKey, CreateRecordSet); + Provider = manager.Owner.Session.Domain.EntityFetchQueryCache.GetOrAdd(cacheKey, static k => CreateRecordSet(k)); if (session.Domain.TagsEnabled && session.Tags != null) { foreach (var tag in session.Tags) { Provider = new TagProvider(Provider, tag); @@ -192,13 +195,7 @@ public EntityGroupTask(TypeInfo type, IReadOnlyList columnIndexes, Prefe this.type = type; this.manager = manager; - var cachedHashCode = 0; - foreach (var columnIndex in columnIndexes) { - cachedHashCode = unchecked (379 * cachedHashCode + columnIndex); - } - - cachedHashCode ^= type.GetHashCode(); - cacheKey = new RecordSetCacheKey(columnIndexes, type, cachedHashCode); + cacheKey = new RecordSetCacheKey(columnIndexes, type); } } } diff --git a/Orm/Xtensive.Orm/Orm/Internals/Prefetch/EntitySetTask.cs b/Orm/Xtensive.Orm/Orm/Internals/Prefetch/EntitySetTask.cs index dc4739a6d..88046ed36 100644 --- a/Orm/Xtensive.Orm/Orm/Internals/Prefetch/EntitySetTask.cs +++ b/Orm/Xtensive.Orm/Orm/Internals/Prefetch/EntitySetTask.cs @@ -4,11 +4,6 @@ // Created by: Alexander Nikolaev // Created: 2009.09.09 -using System; -using System.Collections.Generic; -using System.Linq; -using System.Linq.Expressions; -using System.Reflection; using Xtensive.Core; using Xtensive.Orm.Linq; using Xtensive.Orm.Model; @@ -173,7 +168,7 @@ private QueryTask CreateQueryTask() var session = manager.Owner.Session; var scope = new CompiledQueryProcessingScope(null, null, parameterContext, false); - QueryProvider = session.StorageNode.EntitySetFetchQueryCache.GetOrAdd(cacheKey, CreateRecordSetLoadingItems); + QueryProvider = session.Domain.EntitySetFetchQueryCache.GetOrAdd(cacheKey, static k => CreateRecordSetLoadingItems(k)); if (session.Domain.TagsEnabled && session.Tags != null) { foreach (var tag in session.Tags) { QueryProvider = new TagProvider(QueryProvider, tag); diff --git a/Orm/Xtensive.Orm/Orm/Internals/Prefetch/PrefetchHelper.cs b/Orm/Xtensive.Orm/Orm/Internals/Prefetch/PrefetchHelper.cs index b9d6f2f41..a18c9b15a 100644 --- a/Orm/Xtensive.Orm/Orm/Internals/Prefetch/PrefetchHelper.cs +++ b/Orm/Xtensive.Orm/Orm/Internals/Prefetch/PrefetchHelper.cs @@ -75,14 +75,9 @@ public static bool AddColumns(IEnumerable candidateColumns, return result; } - public static List GetColumnsToBeLoaded(SortedDictionary userColumnIndexes, - TypeInfo type) - { - var result = new List(userColumnIndexes.Count); - result.AddRange(type.Indexes.PrimaryIndex.ColumnIndexMap.System); - result.AddRange(userColumnIndexes.Where(pair => !pair.Value.IsPrimaryKey - && !pair.Value.IsSystem).Select(pair => pair.Key)); - return result; - } + public static IReadOnlyList GetColumnsToBeLoaded(SortedDictionary userColumnIndexes, TypeInfo type) => + type.Indexes.PrimaryIndex.ColumnIndexMap.System + .Concat(userColumnIndexes.Where(pair => !pair.Value.IsPrimaryKey && !pair.Value.IsSystem).Select(pair => pair.Key)) + .ToArray(); } -} \ No newline at end of file +} diff --git a/Orm/Xtensive.Orm/Orm/Internals/Prefetch/PrefetchManager.cs b/Orm/Xtensive.Orm/Orm/Internals/Prefetch/PrefetchManager.cs index cffb6bdc3..ae0f70970 100644 --- a/Orm/Xtensive.Orm/Orm/Internals/Prefetch/PrefetchManager.cs +++ b/Orm/Xtensive.Orm/Orm/Internals/Prefetch/PrefetchManager.cs @@ -49,25 +49,11 @@ public RootContainerCacheKey(TypeInfo type, IEnumerable } } - private class RootContainerCacheEntry - { - public readonly RootContainerCacheKey Key; - - public readonly SortedDictionary Columns; - - public readonly IReadOnlyList ColumnsToBeLoaded; - - - // Constructors - - public RootContainerCacheEntry(in RootContainerCacheKey key, SortedDictionary columns, - IReadOnlyList columnsToBeLoaded) - { - Key = key; - Columns = columns; - ColumnsToBeLoaded = columnsToBeLoaded; - } - } + private record struct RootContainerCacheEntry( + RootContainerCacheKey Key, + SortedDictionary Columns, + IReadOnlyList ColumnsToBeLoaded + ); #endregion @@ -257,7 +243,7 @@ public void GetCachedColumnIndexes(TypeInfo type, { var cacheKey = new RootContainerCacheKey(type, descriptors); var cacheEntry = columnsCache[cacheKey, true]; - if (cacheEntry == null) { + if (cacheEntry == default) { columns = PrefetchHelper.GetColumns(ExtractColumns(descriptors),type); columnsToBeLoaded = PrefetchHelper.GetColumnsToBeLoaded(columns, type); cacheEntry = new RootContainerCacheEntry(cacheKey, columns, columnsToBeLoaded); diff --git a/Orm/Xtensive.Orm/Orm/Model/InheritanceSchema.cs b/Orm/Xtensive.Orm/Orm/Model/InheritanceSchema.cs index 001e866d0..b63e96e77 100644 --- a/Orm/Xtensive.Orm/Orm/Model/InheritanceSchema.cs +++ b/Orm/Xtensive.Orm/Orm/Model/InheritanceSchema.cs @@ -10,7 +10,7 @@ namespace Xtensive.Orm.Model /// Enumerates all supported 'class to tables mapping' schemes. /// /// See M.Fowler - "Patterns of Enterprise Application Architecture". - public enum InheritanceSchema + public enum InheritanceSchema : byte { /// /// Is equal to . @@ -30,4 +30,4 @@ public enum InheritanceSchema /// ConcreteTable = 2 } -} \ No newline at end of file +} diff --git a/Orm/Xtensive.Orm/Orm/PersistenceState.cs b/Orm/Xtensive.Orm/Orm/PersistenceState.cs index 2ae6b2b69..7bda3240a 100644 --- a/Orm/Xtensive.Orm/Orm/PersistenceState.cs +++ b/Orm/Xtensive.Orm/Orm/PersistenceState.cs @@ -9,7 +9,7 @@ namespace Xtensive.Orm /// /// Defines possible persistence states of the entities. /// - public enum PersistenceState + public enum PersistenceState : byte { /// /// The entity is synchronized with the database (there are no unsaved changes). @@ -28,4 +28,4 @@ public enum PersistenceState /// Removed = 3, } -} \ No newline at end of file +} diff --git a/Orm/Xtensive.Orm/Orm/Providers/SessionHandler.References.cs b/Orm/Xtensive.Orm/Orm/Providers/SessionHandler.References.cs index 5ed8b074e..a3db2deaf 100644 --- a/Orm/Xtensive.Orm/Orm/Providers/SessionHandler.References.cs +++ b/Orm/Xtensive.Orm/Orm/Providers/SessionHandler.References.cs @@ -29,7 +29,7 @@ public virtual IEnumerable GetReferencesTo(Entity target, Associa { if (association.IsPaired) return FindReferences(target, association, true); - var (recordSet, parameter) = Session.StorageNode.RefsToEntityQueryCache .GetOrAdd(association, BuildReferencingQuery); + var (recordSet, parameter) = Session.Domain.RefsToEntityQueryCache.GetOrAdd(association, static k => BuildReferencingQuery(k)); var parameterContext = new ParameterContext(); parameterContext.SetValue(parameter, target.Key.Value); ExecutableProvider executableProvider = Session.Compile(recordSet); diff --git a/Orm/Xtensive.Orm/Orm/Providers/SessionHandler.cs b/Orm/Xtensive.Orm/Orm/Providers/SessionHandler.cs index b6ac66b3b..a10181f98 100644 --- a/Orm/Xtensive.Orm/Orm/Providers/SessionHandler.cs +++ b/Orm/Xtensive.Orm/Orm/Providers/SessionHandler.cs @@ -22,7 +22,7 @@ public abstract partial class SessionHandler : IDisposable, IAsyncDisposable /// /// Gets . /// - protected HandlerAccessor Handlers { get; private set; } + protected HandlerAccessor Handlers => Session.Handlers; /// /// Gets the current . @@ -117,7 +117,6 @@ public virtual void Dispose() protected SessionHandler(Session session) { Session = session; - Handlers = session.Handlers; } } -} \ No newline at end of file +} diff --git a/Orm/Xtensive.Orm/Orm/Session.cs b/Orm/Xtensive.Orm/Orm/Session.cs index 298c5b93f..200de0379 100644 --- a/Orm/Xtensive.Orm/Orm/Session.cs +++ b/Orm/Xtensive.Orm/Orm/Session.cs @@ -235,7 +235,7 @@ public static Func Resolver internal SessionHandler Handler { get; set; } - internal HandlerAccessor Handlers { get; private set; } + internal HandlerAccessor Handlers => Domain.Handlers; internal SyncManager PairSyncManager { get; } @@ -546,7 +546,6 @@ internal Session(Domain domain, StorageNode selectedStorageNode, SessionConfigur storageNode = selectedStorageNode; // Handlers - Handlers = domain.Handlers; Handler = CreateSessionHandler(); // Caches, registry diff --git a/Orm/Xtensive.Orm/Orm/StorageNode.cs b/Orm/Xtensive.Orm/Orm/StorageNode.cs index fc130bceb..3f15317bc 100644 --- a/Orm/Xtensive.Orm/Orm/StorageNode.cs +++ b/Orm/Xtensive.Orm/Orm/StorageNode.cs @@ -4,11 +4,7 @@ // Created by: Denis Krjuchkov // Created: 2014.03.13 -using System; using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; using Xtensive.Core; using Xtensive.Orm.Configuration; using Xtensive.Orm.Interfaces; @@ -31,7 +27,7 @@ public sealed class StorageNode : ISessionSource /// /// Gets node identifier. /// - public string Id { get { return Configuration.NodeId; } } + public string Id => Configuration.NodeId; /// /// Gets node configuration. @@ -53,25 +49,12 @@ public sealed class StorageNode : ISessionSource /// internal ConcurrentDictionary<(TypeInfo, LockMode, LockBehavior), ExecutableProvider> EntityLockProviderCache { get; } = new(); - /// - /// Caches uncompiled queries used by to fetch certain entities. - /// - internal ConcurrentDictionary EntityFetchQueryCache { get; } = new(); - - /// - /// Caches uncompiled queries used by to fetch content. - /// - internal ConcurrentDictionary EntitySetFetchQueryCache { get; } = new(); /// /// Caches certain info about EntitySet fields, e.g. queries to fetch current count or items. /// internal ConcurrentDictionary EntitySetTypeStateCache { get; } = new(); - /// - /// Caches queries that get references to entities for certain association. - /// - internal ConcurrentDictionary)> RefsToEntityQueryCache { get; } = new(); internal ConcurrentDictionary KeySequencesCache { get; } = new(); internal ConcurrentDictionary> PersistRequestCache { get; } = new(); diff --git a/Orm/Xtensive.Orm/Orm/TypeReference.cs b/Orm/Xtensive.Orm/Orm/TypeReference.cs index 93faa6d0f..f6dc6be4d 100644 --- a/Orm/Xtensive.Orm/Orm/TypeReference.cs +++ b/Orm/Xtensive.Orm/Orm/TypeReference.cs @@ -4,40 +4,12 @@ // Created by: Dmitri Maximov // Created: 2009.10.09 -using System; - using Xtensive.Orm.Model; -namespace Xtensive.Orm -{ - /// - /// Reference to with the specified degree of accuracy. - /// - [Serializable] - public readonly struct TypeReference - { - /// - /// Gets the referenced type. - /// - public TypeInfo Type { get; } - - /// - /// Gets the type reference accuracy. - /// - public TypeReferenceAccuracy Accuracy { get; } - - - // Constructor +namespace Xtensive.Orm; - /// - /// Initializes a new instance of this class. - /// - /// The referenced type. - /// The type reference accuracy. - public TypeReference(TypeInfo type, TypeReferenceAccuracy accuracy) - { - Type = type; - Accuracy = accuracy; - } - } -} +/// +/// Reference to with the specified degree of accuracy. +/// +[Serializable] +public record struct TypeReference(TypeInfo Type, TypeReferenceAccuracy Accuracy); diff --git a/Orm/Xtensive.Orm/Orm/TypeReferenceAccuracy.cs b/Orm/Xtensive.Orm/Orm/TypeReferenceAccuracy.cs index 01b3c34fe..ba2175e66 100644 --- a/Orm/Xtensive.Orm/Orm/TypeReferenceAccuracy.cs +++ b/Orm/Xtensive.Orm/Orm/TypeReferenceAccuracy.cs @@ -9,7 +9,7 @@ namespace Xtensive.Orm /// /// Describes type reference accuracy. /// - public enum TypeReferenceAccuracy + public enum TypeReferenceAccuracy : byte { /// /// Referenced type is limited to the entire hierarchy. @@ -26,4 +26,4 @@ public enum TypeReferenceAccuracy /// ExactType = 2, } -} \ No newline at end of file +}