From e6f9c22fd7c3fdb45b0461cd56c2291cdeefee74 Mon Sep 17 00:00:00 2001 From: Olmo del Corral Cano Date: Wed, 7 Feb 2024 16:50:28 +0100 Subject: [PATCH 1/4] fix VersionChangedAlert --- Signum/React/Frames/VersionChangedAlert.css | 2 -- 1 file changed, 2 deletions(-) diff --git a/Signum/React/Frames/VersionChangedAlert.css b/Signum/React/Frames/VersionChangedAlert.css index 2ce90d540d..5629da1ce4 100644 --- a/Signum/React/Frames/VersionChangedAlert.css +++ b/Signum/React/Frames/VersionChangedAlert.css @@ -1,7 +1,5 @@ .version-alert { text-align:center; - margin-top:10px; - margin-bottom: 0px; font-size: 1.3em; flex-grow: 0 !important; } From e971f094a62e0d42d551c5cca05f6c907a06852e Mon Sep 17 00:00:00 2001 From: Olmo del Corral Cano Date: Wed, 7 Feb 2024 16:50:54 +0100 Subject: [PATCH 2/4] fix EmailModelLogic parameter name --- Extensions/Signum.Mailing/EmailModelLogic.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Extensions/Signum.Mailing/EmailModelLogic.cs b/Extensions/Signum.Mailing/EmailModelLogic.cs index bb21cd99d9..7206f69eb5 100644 --- a/Extensions/Signum.Mailing/EmailModelLogic.cs +++ b/Extensions/Signum.Mailing/EmailModelLogic.cs @@ -73,7 +73,7 @@ public virtual List GetFilters(QueryDescription qd) throw new InvalidOperationException($"Since {typeof(T).Name} is not in {imp}, it's necessary to override ${nameof(GetFilters)} in ${this.GetType().Name}"); } - public virtual List GetOrders(QueryDescription queryDescription) + public virtual List GetOrders(QueryDescription qd) { return new List(); } From c23418db4abcb53759f206ccdf91ea94270a37ac Mon Sep 17 00:00:00 2001 From: Olmo del Corral Cano Date: Thu, 8 Feb 2024 14:18:50 +0100 Subject: [PATCH 3/4] add and apply Upgrade_20240208_Frozen --- Extensions/Signum.Authorization/AuthLogic.cs | 15 +++++----- Extensions/Signum.Authorization/AuthServer.cs | 5 ++-- .../ColorPalette/ChartColorLogic.cs | 6 ++-- .../Signum.Chart/UserChart/UserChartLogic.cs | 13 ++++---- Extensions/Signum.Dashboard/DashboardLogic.cs | 13 ++++---- .../Signum.Eval/TypeHelp/TypeHelpLogic.cs | 9 +++--- Extensions/Signum.Mailing/EmailModelLogic.cs | 13 ++++---- .../EmailSenderConfigurationLogic.cs | 5 ++-- .../Templates/EmailTemplateLogic.cs | 9 +++--- Extensions/Signum.Scheduler/SchedulerLogic.cs | 5 ++-- Extensions/Signum.Toolbar/ToolbarLogic.cs | 9 +++--- .../Instances/TranslatedInstanceLogic.cs | 6 ++-- .../Signum.UserQueries/UserQueryLogic.cs | 17 ++++++----- Extensions/Signum.Word/WordModelLogic.cs | 14 +++++---- Extensions/Signum.Word/WordTemplateLogic.cs | 14 +++++---- .../Upgrades/Upgrade_20240208_Frozen.cs | 24 +++++++++++++++ .../Extensions/DictionaryExtensions.cs | 21 +++++++++++++ Signum.Utilities/MyRandom.cs | 23 -------------- Signum/API/ReflectionServer.cs | 4 +-- Signum/Basics/CultureInfoLogic.cs | 9 +++--- Signum/Basics/PropertyRouteLogic.cs | 5 ++-- Signum/Basics/QueryLogic.cs | 15 +++++----- Signum/Basics/SemiSymbolLogic.cs | 7 +++-- Signum/Basics/SymbolLogic.cs | 7 +++-- Signum/Engine/Connection/SqlServerRetry.cs | 2 +- Signum/Entities/Reflection/Reflector.cs | 30 +++++++++---------- Signum/Operations/OperationLogic.cs | 5 ++-- 27 files changed, 177 insertions(+), 128 deletions(-) create mode 100644 Signum.Upgrade/Upgrades/Upgrade_20240208_Frozen.cs diff --git a/Extensions/Signum.Authorization/AuthLogic.cs b/Extensions/Signum.Authorization/AuthLogic.cs index 4bef70749d..f8b4bce859 100644 --- a/Extensions/Signum.Authorization/AuthLogic.cs +++ b/Extensions/Signum.Authorization/AuthLogic.cs @@ -3,6 +3,7 @@ using Signum.Authorization.Rules; using Signum.Utilities.DataStructures; using Signum.Utilities.Reflection; +using System.Collections.Frozen; using System.IO; using System.Xml.Linq; @@ -45,8 +46,8 @@ public static IQueryable Users(this RoleEntity r) => static ResetLazy>> rolesGraph = null!; static ResetLazy>> rolesInverse = null!; - static ResetLazy>> rolesByName = null!; - public static ResetLazy, RoleEntity>> RolesByLite = null!; + static ResetLazy>> rolesByName = null!; + public static ResetLazy, RoleEntity>> RolesByLite = null!; @@ -56,7 +57,7 @@ class RoleData public MergeStrategy MergeStrategy; } - static ResetLazy, RoleData>> mergeStrategies = null!; + static ResetLazy, RoleData>> mergeStrategies = null!; public static void AssertStarted(SchemaBuilder sb) { @@ -108,8 +109,8 @@ public static void Start(SchemaBuilder sb, string? systemUserName, string? anony - RolesByLite = sb.GlobalLazy(() => Database.Query().ToDictionaryEx(a => a.ToLite()), new InvalidateWith(typeof(RoleEntity)), AuthLogic.NotifyRulesChanged); - rolesByName = sb.GlobalLazy(() => RolesByLite.Value.Keys.ToDictionaryEx(a => a.ToString()!), new InvalidateWith(typeof(RoleEntity))); + RolesByLite = sb.GlobalLazy(() => Database.Query().ToFrozenDictionaryEx(a => a.ToLite()), new InvalidateWith(typeof(RoleEntity)), AuthLogic.NotifyRulesChanged); + rolesByName = sb.GlobalLazy(() => RolesByLite.Value.Keys.ToFrozenDictionaryEx(a => a.ToString()!), new InvalidateWith(typeof(RoleEntity))); rolesGraph = sb.GlobalLazy(() => CacheRoles(RolesByLite.Value), new InvalidateWith(typeof(RoleEntity))); rolesInverse = sb.GlobalLazy(() => rolesGraph.Value.Inverse(), new InvalidateWith(typeof(RoleEntity))); mergeStrategies = sb.GlobalLazy(() => @@ -132,7 +133,7 @@ public static void Start(SchemaBuilder sb, string? systemUserName, string? anony }); } - return result; + return result.ToFrozenDictionary(); }, new InvalidateWith(typeof(RoleEntity))); sb.Schema.EntityEvents().Saving += Schema_Saving; @@ -259,7 +260,7 @@ static void Schema_Saving(RoleEntity role) } } - static DirectedGraph> CacheRoles(Dictionary, RoleEntity> rolesLite) + static DirectedGraph> CacheRoles(FrozenDictionary, RoleEntity> rolesLite) { var graph = DirectedGraph>.Generate(rolesLite.Keys, r => rolesLite.GetOrThrow(r).InheritsFrom); diff --git a/Extensions/Signum.Authorization/AuthServer.cs b/Extensions/Signum.Authorization/AuthServer.cs index b144ab51c4..5141a14096 100644 --- a/Extensions/Signum.Authorization/AuthServer.cs +++ b/Extensions/Signum.Authorization/AuthServer.cs @@ -11,6 +11,7 @@ using System.Runtime.InteropServices; using System.Collections.Concurrent; using System.Reflection; +using System.Collections.Frozen; namespace Signum.Authorization; @@ -264,8 +265,8 @@ public static void Start(Func tokenConfig, strin } - public static ResetLazy>> entitiesByNamespace = - new ResetLazy>>(() => Schema.Current.Tables.Keys.Where(t => !EnumEntity.IsEnumEntity(t)).GroupToDictionary(t => t.Namespace!)); + public static ResetLazy>> entitiesByNamespace = + new(() => Schema.Current.Tables.Keys.Where(t => !EnumEntity.IsEnumEntity(t)).GroupToDictionary(t => t.Namespace!).ToFrozenDictionary()); public static ConcurrentDictionary NamespaceNoLoaded = new ConcurrentDictionary(); diff --git a/Extensions/Signum.Chart/ColorPalette/ChartColorLogic.cs b/Extensions/Signum.Chart/ColorPalette/ChartColorLogic.cs index 5c378263b7..9a5bd19d03 100644 --- a/Extensions/Signum.Chart/ColorPalette/ChartColorLogic.cs +++ b/Extensions/Signum.Chart/ColorPalette/ChartColorLogic.cs @@ -1,8 +1,10 @@ +using System.Collections.Frozen; + namespace Signum.Chart.ColorPalette; public static class ColorPaletteLogic { - public static ResetLazy> ColorPaletteCache = null!; + public static ResetLazy> ColorPaletteCache = null!; public static readonly int Limit = 360; @@ -24,7 +26,7 @@ internal static void Start(SchemaBuilder sb) ColorPaletteCache = sb.GlobalLazy(() => Database.Query() - .ToDictionaryEx(cc => cc.Type.ToType()), + .ToFrozenDictionaryEx(cc => cc.Type.ToType()), new InvalidateWith(typeof(ColorPaletteEntity))); } } diff --git a/Extensions/Signum.Chart/UserChart/UserChartLogic.cs b/Extensions/Signum.Chart/UserChart/UserChartLogic.cs index 4ce0fc091e..1e54dc434d 100644 --- a/Extensions/Signum.Chart/UserChart/UserChartLogic.cs +++ b/Extensions/Signum.Chart/UserChart/UserChartLogic.cs @@ -8,14 +8,15 @@ using Signum.UserAssets.QueryTokens; using Signum.UserQueries; using Signum.ViewLog; +using System.Collections.Frozen; namespace Signum.Chart.UserChart; public static class UserChartLogic { - public static ResetLazy, UserChartEntity>> UserCharts = null!; - public static ResetLazy>>> UserChartsByType = null!; - public static ResetLazy>>> UserChartsByQuery = null!; + public static ResetLazy, UserChartEntity>> UserCharts = null!; + public static ResetLazy>>> UserChartsByType = null!; + public static ResetLazy>>> UserChartsByQuery = null!; [AutoExpressionField] public static IQueryable CachedQueries(this UserChartEntity uc) => @@ -147,15 +148,15 @@ public static void Start(SchemaBuilder sb) Administrator.UnsafeDeletePreCommand(Database.Query().Where(a => a.Query.Is(e))); - UserCharts = sb.GlobalLazy(() => Database.Query().ToDictionary(a => a.ToLite()), + UserCharts = sb.GlobalLazy(() => Database.Query().ToFrozenDictionaryEx(a => a.ToLite()), new InvalidateWith(typeof(UserChartEntity))); - UserChartsByQuery = sb.GlobalLazy(() => UserCharts.Value.Values.Where(a => a.EntityType == null).SelectCatch(uc => KeyValuePair.Create(uc.Query.ToQueryName(), uc.ToLite())).GroupToDictionary(), + UserChartsByQuery = sb.GlobalLazy(() => UserCharts.Value.Values.Where(a => a.EntityType == null).SelectCatch(uc => KeyValuePair.Create(uc.Query.ToQueryName(), uc.ToLite())).GroupToDictionary().ToFrozenDictionary(), new InvalidateWith(typeof(UserChartEntity))); UserChartsByType = sb.GlobalLazy(() => UserCharts.Value.Values.Where(a => a.EntityType != null) .SelectCatch(a => KeyValuePair.Create(TypeLogic.IdToType.GetOrThrow(a.EntityType!.Id), a.ToLite())) - .GroupToDictionary(), + .GroupToDictionary().ToFrozenDictionary(), new InvalidateWith(typeof(UserChartEntity))); } } diff --git a/Extensions/Signum.Dashboard/DashboardLogic.cs b/Extensions/Signum.Dashboard/DashboardLogic.cs index 151bd30bfa..128f415454 100644 --- a/Extensions/Signum.Dashboard/DashboardLogic.cs +++ b/Extensions/Signum.Dashboard/DashboardLogic.cs @@ -16,14 +16,15 @@ using Signum.Toolbar; using Signum.API; using Signum.Omnibox; +using System.Collections.Frozen; namespace Signum.Dashboard; public static class DashboardLogic { - public static ResetLazy, DashboardEntity>> Dashboards = null!; - public static ResetLazy, List>> CachedQueriesCache = null!; - public static ResetLazy>>> DashboardsByType = null!; + public static ResetLazy, DashboardEntity>> Dashboards = null!; + public static ResetLazy, List>> CachedQueriesCache = null!; + public static ResetLazy>>> DashboardsByType = null!; public static Polymorphic>> OnGetCachedQueryDefinition = new(); @@ -107,15 +108,15 @@ public static void Start(SchemaBuilder sb, IFileTypeAlgorithm cachedQueryAlgorit DashboardGraph.Register(); - Dashboards = sb.GlobalLazy(() => Database.Query().ToDictionary(a => a.ToLite()), + Dashboards = sb.GlobalLazy(() => Database.Query().ToFrozenDictionary(a => a.ToLite()), new InvalidateWith(typeof(DashboardEntity))); - CachedQueriesCache = sb.GlobalLazy(() => Database.Query().GroupToDictionary(a => a.Dashboard), + CachedQueriesCache = sb.GlobalLazy(() => Database.Query().GroupToDictionary(a => a.Dashboard).ToFrozenDictionary(), new InvalidateWith(typeof(CachedQueryEntity))); DashboardsByType = sb.GlobalLazy(() => Dashboards.Value.Values.Where(a => a.EntityType != null) .SelectCatch(d => KeyValuePair.Create(TypeLogic.IdToType.GetOrThrow(d.EntityType!.Id), d.ToLite())) - .GroupToDictionary(), + .GroupToDictionary().ToFrozenDictionary(), new InvalidateWith(typeof(DashboardEntity))); if (sb.WebServerBuilder != null) diff --git a/Extensions/Signum.Eval/TypeHelp/TypeHelpLogic.cs b/Extensions/Signum.Eval/TypeHelp/TypeHelpLogic.cs index 75200a73a9..131b93e34c 100644 --- a/Extensions/Signum.Eval/TypeHelp/TypeHelpLogic.cs +++ b/Extensions/Signum.Eval/TypeHelp/TypeHelpLogic.cs @@ -1,5 +1,6 @@ using Signum.API; using System; +using System.Collections.Frozen; using System.Collections.Generic; using System.Linq; using System.Text; @@ -10,8 +11,8 @@ namespace Signum.Eval.TypeHelp; public static class TypeHelpLogic { - public static ResetLazy> AvailableEmbeddedEntities = null!; - public static ResetLazy> AvailableModelEntities = null!; + public static ResetLazy> AvailableEmbeddedEntities = null!; + public static ResetLazy> AvailableModelEntities = null!; public static void Start(SchemaBuilder sb) { @@ -25,7 +26,7 @@ public static void Start(SchemaBuilder sb) .Distinct() .SelectMany(a => a.GetTypes()) .Where(t => typeof(EmbeddedEntity).IsAssignableFrom(t) && namespaces.Contains(t.Namespace!)) - .ToHashSet(); + .ToFrozenSet(); }, new InvalidateWith()); @@ -37,7 +38,7 @@ public static void Start(SchemaBuilder sb) .Distinct() .SelectMany(a => a.GetTypes()) .Where(t => typeof(ModelEntity).IsAssignableFrom(t) && namespaces.Contains(t.Namespace!)) - .ToHashSet(); + .ToFrozenSet(); }, new InvalidateWith()); diff --git a/Extensions/Signum.Mailing/EmailModelLogic.cs b/Extensions/Signum.Mailing/EmailModelLogic.cs index 7206f69eb5..b3fd79e5bb 100644 --- a/Extensions/Signum.Mailing/EmailModelLogic.cs +++ b/Extensions/Signum.Mailing/EmailModelLogic.cs @@ -4,6 +4,7 @@ using Signum.Templating; using Signum.UserAssets; using Signum.Authorization; +using System.Collections.Frozen; namespace Signum.Mailing; @@ -134,10 +135,10 @@ public EmailModelInfo(object queryName) } } - static ResetLazy, List>> EmailModelToTemplates = null!; + static ResetLazy, List>> EmailModelToTemplates = null!; static Dictionary registeredModels = new Dictionary(); - public static ResetLazy> TypeToEntity = null!; - public static ResetLazy> EntityToType = null!; + public static ResetLazy> TypeToEntity = null!; + public static ResetLazy> EntityToType = null!; public static void Start(SchemaBuilder sb) { @@ -165,7 +166,7 @@ public static void Start(SchemaBuilder sb) from et in Database.Query() where et.Model != null select new { se = et.Model, et }) - .GroupToDictionary(pair => pair.se.ToLite(), pair => pair.et), + .GroupToDictionary(pair => pair.se.ToLite(), pair => pair.et).ToFrozenDictionary(), new InvalidateWith(typeof(EmailModelEntity), typeof(EmailTemplateEntity))); TypeToEntity = sb.GlobalLazy(() => @@ -178,13 +179,13 @@ from et in Database.Query() type => type.FullName!, (entity, type) => KeyValuePair.Create(type, entity), "caching " + nameof(EmailModelEntity)) - .ToDictionary(); + .ToFrozenDictionaryEx(); }, new InvalidateWith(typeof(EmailModelEntity))); sb.Schema.Initializing += () => TypeToEntity.Load(); - EntityToType = sb.GlobalLazy(() => TypeToEntity.Value.Inverse(), + EntityToType = sb.GlobalLazy(() => TypeToEntity.Value.Inverse().ToFrozenDictionaryEx(), new InvalidateWith(typeof(EmailModelEntity))); } } diff --git a/Extensions/Signum.Mailing/EmailSenderConfigurationLogic.cs b/Extensions/Signum.Mailing/EmailSenderConfigurationLogic.cs index 4314cf5ae8..c6168d0afc 100644 --- a/Extensions/Signum.Mailing/EmailSenderConfigurationLogic.cs +++ b/Extensions/Signum.Mailing/EmailSenderConfigurationLogic.cs @@ -1,12 +1,13 @@ using System.Net.Mail; using System.Net; using System.Security.Cryptography.X509Certificates; +using System.Collections.Frozen; namespace Signum.Mailing; public static class EmailSenderConfigurationLogic { - public static ResetLazy, EmailSenderConfigurationEntity>> EmailSenderCache = null!; + public static ResetLazy, EmailSenderConfigurationEntity>> EmailSenderCache = null!; public static Func EncryptPassword = s => s; public static Func DecryptPassword = s => s; @@ -33,7 +34,7 @@ public static void Start(SchemaBuilder sb, Func? encryptPassword s.Service }); - EmailSenderCache = sb.GlobalLazy(() => Database.Query().ToDictionary(a => a.ToLite()), + EmailSenderCache = sb.GlobalLazy(() => Database.Query().ToFrozenDictionaryEx(a => a.ToLite()), new InvalidateWith(typeof(EmailSenderConfigurationEntity))); new Graph.Execute(EmailSenderConfigurationOperation.Save) diff --git a/Extensions/Signum.Mailing/Templates/EmailTemplateLogic.cs b/Extensions/Signum.Mailing/Templates/EmailTemplateLogic.cs index 09c304eb57..6e07adcb77 100644 --- a/Extensions/Signum.Mailing/Templates/EmailTemplateLogic.cs +++ b/Extensions/Signum.Mailing/Templates/EmailTemplateLogic.cs @@ -8,6 +8,7 @@ using Signum.UserAssets.Queries; using Signum.API; using Signum.Authorization; +using System.Collections.Frozen; namespace Signum.Mailing.Templates; @@ -27,8 +28,8 @@ public static class EmailTemplateLogic public static IQueryable EmailTemplates(this EmailModelEntity se) => As.Expression(() => Database.Query().Where(et => et.Model.Is(se))); - public static ResetLazy, EmailTemplateEntity>> EmailTemplatesLazy = null!; - public static ResetLazy>> TemplatesByQueryName = null!; + public static ResetLazy, EmailTemplateEntity>> EmailTemplatesLazy = null!; + public static ResetLazy>> TemplatesByQueryName = null!; public static Polymorphic> FillAttachmentTokens = @@ -98,12 +99,12 @@ public static void Start(SchemaBuilder sb, Func - Database.Query().ToDictionary(et => et.ToLite()) + Database.Query().ToFrozenDictionaryEx(et => et.ToLite()) , new InvalidateWith(typeof(EmailTemplateEntity))); TemplatesByQueryName = sb.GlobalLazy(() => { - return EmailTemplatesLazy.Value.Values.SelectCatch(et => KeyValuePair.Create(et.Query.ToQueryName(), et)).GroupToDictionary(); + return EmailTemplatesLazy.Value.Values.SelectCatch(et => KeyValuePair.Create(et.Query.ToQueryName(), et)).GroupToDictionary().ToFrozenDictionaryEx(); }, new InvalidateWith(typeof(EmailTemplateEntity))); EmailModelLogic.Start(sb); diff --git a/Extensions/Signum.Scheduler/SchedulerLogic.cs b/Extensions/Signum.Scheduler/SchedulerLogic.cs index 267630de3f..33f2635560 100644 --- a/Extensions/Signum.Scheduler/SchedulerLogic.cs +++ b/Extensions/Signum.Scheduler/SchedulerLogic.cs @@ -5,6 +5,7 @@ using Signum.Authorization; using Signum.Authorization.Rules; using Signum.API; +using System.Collections.ObjectModel; namespace Signum.Scheduler; @@ -32,7 +33,7 @@ public static IQueryable ExceptionLines(this S public static Action? OnFinally; - public static ResetLazy> ScheduledTasksLazy = null!; + public static ResetLazy> ScheduledTasksLazy = null!; public static void Start(SchemaBuilder sb) { @@ -151,7 +152,7 @@ public static void Start(SchemaBuilder sb) ScheduledTasksLazy = sb.GlobalLazy(() => Database.Query().Where(a => !a.Suspended && - (a.MachineName == ScheduledTaskEntity.None || a.MachineName == Schema.Current.MachineName && a.ApplicationName == Schema.Current.ApplicationName)).ToList(), + (a.MachineName == ScheduledTaskEntity.None || a.MachineName == Schema.Current.MachineName && a.ApplicationName == Schema.Current.ApplicationName)).ToReadOnly(), new InvalidateWith(typeof(ScheduledTaskEntity))); ScheduledTasksLazy.OnReset += ScheduleTaskRunner.ScheduledTasksLazy_OnReset; diff --git a/Extensions/Signum.Toolbar/ToolbarLogic.cs b/Extensions/Signum.Toolbar/ToolbarLogic.cs index fc1c91ab3c..651f932de3 100644 --- a/Extensions/Signum.Toolbar/ToolbarLogic.cs +++ b/Extensions/Signum.Toolbar/ToolbarLogic.cs @@ -2,14 +2,15 @@ using Signum.Authorization.Rules; using Signum.UserAssets; using Signum.Utilities.DataStructures; +using System.Collections.Frozen; using System.Text.Json.Serialization; namespace Signum.Toolbar; public static class ToolbarLogic { - public static ResetLazy, ToolbarEntity>> Toolbars = null!; - public static ResetLazy, ToolbarMenuEntity>> ToolbarMenus = null!; + public static ResetLazy, ToolbarEntity>> Toolbars = null!; + public static ResetLazy, ToolbarMenuEntity>> ToolbarMenus = null!; public static Dictionary>> CustomPermissionResponse = new Dictionary>>(); @@ -103,10 +104,10 @@ public static void Start(SchemaBuilder sb) //{ typeof(WorkflowEntity), a => { var wf = WorkflowLogic.WorkflowGraphLazy.Value.GetOrCreate((Lite)a); return InMemoryFilter(wf.Workflow) && wf.IsStartCurrentUser(); } }, - Toolbars = sb.GlobalLazy(() => Database.Query().ToDictionary(a => a.ToLite()), + Toolbars = sb.GlobalLazy(() => Database.Query().ToFrozenDictionaryEx(a => a.ToLite()), new InvalidateWith(typeof(ToolbarEntity))); - ToolbarMenus = sb.GlobalLazy(() => Database.Query().ToDictionary(a => a.ToLite()), + ToolbarMenus = sb.GlobalLazy(() => Database.Query().ToFrozenDictionaryEx(a => a.ToLite()), new InvalidateWith(typeof(ToolbarMenuEntity))); } } diff --git a/Extensions/Signum.Translation/Instances/TranslatedInstanceLogic.cs b/Extensions/Signum.Translation/Instances/TranslatedInstanceLogic.cs index a536c8ad7d..f319b14267 100644 --- a/Extensions/Signum.Translation/Instances/TranslatedInstanceLogic.cs +++ b/Extensions/Signum.Translation/Instances/TranslatedInstanceLogic.cs @@ -10,6 +10,7 @@ using Signum.Engine.Sync; using Signum.Excel; using Signum.UserAssets; +using System.Collections.Frozen; namespace Signum.Translation.Instances; @@ -18,7 +19,7 @@ public static class TranslatedInstanceLogic static Func getDefaultCulture = null!; public static CultureInfo DefaultCulture { get { return getDefaultCulture(); } } - static ResetLazy>> LocalizationCache = null!; + static ResetLazy>> LocalizationCache = null!; public static void Start(SchemaBuilder sb, Func defaultCulture) { @@ -60,7 +61,8 @@ public static void Start(SchemaBuilder sb, Func defaultCulture) return gr.Select(ti => KeyValuePair.Create(new LocalizedInstanceKey(pr, ti.Instance, new PrimaryKey((IComparable)ReflectionTools.Parse(ti.RowId!, type)!)), ti)); - }).ToDictionary()) + }).ToFrozenDictionaryEx()) + .ToFrozenDictionaryEx() , new InvalidateWith(typeof(TranslatedInstanceEntity))); PropertyRouteTranslationLogic.TranslatedFieldFunc = (Lite lite, PropertyRoute route, PrimaryKey? rowId, string? fallbackString) => diff --git a/Extensions/Signum.UserQueries/UserQueryLogic.cs b/Extensions/Signum.UserQueries/UserQueryLogic.cs index 5c029b65e0..1603c4849c 100644 --- a/Extensions/Signum.UserQueries/UserQueryLogic.cs +++ b/Extensions/Signum.UserQueries/UserQueryLogic.cs @@ -10,15 +10,16 @@ using Signum.UserAssets.Queries; using Signum.UserAssets.QueryTokens; using Signum.ViewLog; +using System.Collections.Frozen; using System.Linq.Expressions; namespace Signum.UserQueries; public static class UserQueryLogic { - public static ResetLazy, UserQueryEntity>> UserQueries = null!; - public static ResetLazy>>> UserQueriesByType = null!; - public static ResetLazy>>> UserQueriesByQuery = null!; + public static ResetLazy, UserQueryEntity>> UserQueries = null!; + public static ResetLazy>>> UserQueriesByType = null!; + public static ResetLazy>>> UserQueriesByQuery = null!; [AutoExpressionField] public static IQueryable CachedQueries(this UserQueryEntity uq) => @@ -131,15 +132,17 @@ public static void Start(SchemaBuilder sb) sb.Schema.EntityEvents().Retrieved += UserQueryLogic_Retrieved; - UserQueries = sb.GlobalLazy(() => Database.Query().ToDictionary(a => a.ToLite()), + UserQueries = sb.GlobalLazy(() => Database.Query().ToFrozenDictionaryEx(a => a.ToLite()), new InvalidateWith(typeof(UserQueryEntity))); - UserQueriesByQuery = sb.GlobalLazy(() => UserQueries.Value.Values.Where(a => a.EntityType == null).SelectCatch(uq => KeyValuePair.Create(uq.Query.ToQueryName(), uq.ToLite())).GroupToDictionary(), + UserQueriesByQuery = sb.GlobalLazy(() => UserQueries.Value.Values.Where(a => a.EntityType == null) + .SelectCatch(uq => KeyValuePair.Create(uq.Query.ToQueryName(), uq.ToLite())).GroupToDictionary().ToFrozenDictionaryEx(), new InvalidateWith(typeof(UserQueryEntity))); UserQueriesByType = sb.GlobalLazy(() => UserQueries.Value.Values.Where(a => a.EntityType != null) - .SelectCatch(uq => KeyValuePair.Create(TypeLogic.IdToType.GetOrThrow(uq.EntityType!.Id), uq.ToLite())) - .GroupToDictionary(), new InvalidateWith(typeof(UserQueryEntity))); + .SelectCatch(uq => KeyValuePair.Create(TypeLogic.IdToType.GetOrThrow(uq.EntityType!.Id), uq.ToLite())) + .GroupToDictionary().ToFrozenDictionaryEx(), + new InvalidateWith(typeof(UserQueryEntity))); if (sb.WebServerBuilder != null) { diff --git a/Extensions/Signum.Word/WordModelLogic.cs b/Extensions/Signum.Word/WordModelLogic.cs index 020e4d1955..0ac3e034c7 100644 --- a/Extensions/Signum.Word/WordModelLogic.cs +++ b/Extensions/Signum.Word/WordModelLogic.cs @@ -1,3 +1,4 @@ +using System.Collections.Frozen; using System.Globalization; using DocumentFormat.OpenXml.Packaging; using Signum.DynamicQuery.Tokens; @@ -136,10 +137,10 @@ public WordModelInfo(object queryName) } } - static ResetLazy, List>>> WordModelToTemplates = null!; + static ResetLazy, List>>> WordModelToTemplates = null!; static Dictionary registeredWordModels = new Dictionary(); - public static ResetLazy> WordModelTypeToEntity = null!; - public static ResetLazy> WordModelEntityToType = null!; + public static ResetLazy> WordModelTypeToEntity = null!; + public static ResetLazy> WordModelEntityToType = null!; public static void Start(SchemaBuilder sb) { @@ -168,7 +169,8 @@ public static void Start(SchemaBuilder sb) from et in Database.Query() where et.Model != null select new { swe = et.Model, et = et.ToLite() }) - .GroupToDictionary(pair => pair.swe!.ToLite(), pair => pair.et!), + .GroupToDictionary(pair => pair.swe!.ToLite(), pair => pair.et!) + .ToFrozenDictionaryEx(), new InvalidateWith(typeof(WordModelEntity), typeof(WordTemplateEntity))); WordModelTypeToEntity = sb.GlobalLazy(() => @@ -180,12 +182,12 @@ from et in Database.Query() swr => swr.FullClassName, type => type.FullName!, (swr, type) => KeyValuePair.Create(type, swr), - "caching " + nameof(WordModelEntity)).ToDictionary(); + "caching " + nameof(WordModelEntity)).ToFrozenDictionaryEx(); }, new InvalidateWith(typeof(WordModelEntity))); sb.Schema.Initializing += () => WordModelTypeToEntity.Load(); - WordModelEntityToType = sb.GlobalLazy(() => WordModelTypeToEntity.Value.Inverse(), + WordModelEntityToType = sb.GlobalLazy(() => WordModelTypeToEntity.Value.Inverse().ToFrozenDictionaryEx(), new InvalidateWith(typeof(WordModelEntity))); } } diff --git a/Extensions/Signum.Word/WordTemplateLogic.cs b/Extensions/Signum.Word/WordTemplateLogic.cs index 8776e0f6fc..601f4e5e17 100644 --- a/Extensions/Signum.Word/WordTemplateLogic.cs +++ b/Extensions/Signum.Word/WordTemplateLogic.cs @@ -12,6 +12,7 @@ using Signum.UserAssets; using Signum.UserAssets.Queries; using Signum.API; +using System.Collections.Frozen; namespace Signum.Word; @@ -26,10 +27,10 @@ public static class WordTemplateLogic { public static bool AvoidSynchronize = false; - public static ResetLazy, WordTemplateEntity>> WordTemplatesLazy = null!; + public static ResetLazy, WordTemplateEntity>> WordTemplatesLazy = null!; - public static ResetLazy>> TemplatesByQueryName = null!; - public static ResetLazy>> TemplatesByEntityType = null!; + public static ResetLazy>> TemplatesByQueryName = null!; + public static ResetLazy>> TemplatesByEntityType = null!; public static Dictionary> Transformers = new Dictionary>(); public static Dictionary> Converters = new Dictionary>(); @@ -131,13 +132,13 @@ public static void Start(SchemaBuilder sb) }.Register(); WordTemplatesLazy = sb.GlobalLazy(() => Database.Query() - .ToDictionary(et => et.ToLite()), new InvalidateWith(typeof(WordTemplateEntity))); + .ToFrozenDictionaryEx(et => et.ToLite()), new InvalidateWith(typeof(WordTemplateEntity))); TemplatesByQueryName = sb.GlobalLazy(() => { - return WordTemplatesLazy.Value.Values.SelectCatch(w => KeyValuePair.Create(w.Query.ToQueryName(), w)).GroupToDictionary(); + return WordTemplatesLazy.Value.Values.SelectCatch(w => KeyValuePair.Create(w.Query.ToQueryName(), w)).GroupToDictionary().ToFrozenDictionaryEx(); }, new InvalidateWith(typeof(WordTemplateEntity))); TemplatesByEntityType = sb.GlobalLazy(() => @@ -146,7 +147,8 @@ public static void Start(SchemaBuilder sb) where !pair.imp.IsByAll from t in pair.imp.Types select KeyValuePair.Create(t, pair.wr)) - .GroupToDictionary(); + .GroupToDictionary() + .ToFrozenDictionaryEx(); }, new InvalidateWith(typeof(WordTemplateEntity))); Schema.Current.Synchronizing += Schema_Synchronize_Tokens; diff --git a/Signum.Upgrade/Upgrades/Upgrade_20240208_Frozen.cs b/Signum.Upgrade/Upgrades/Upgrade_20240208_Frozen.cs new file mode 100644 index 0000000000..ad51a954a0 --- /dev/null +++ b/Signum.Upgrade/Upgrades/Upgrade_20240208_Frozen.cs @@ -0,0 +1,24 @@ +using Signum.Utilities; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Signum.Upgrade.Upgrades; + +class Upgrade_20240208_Frozen : CodeUpgradeBase +{ + public override string Description => "Use FrozenDictionary / FrozenSet and Random.Shared"; + + public override void Execute(UpgradeContext uctx) + { + uctx.ForeachCodeFile(@"*.cs", file => + { + file.Replace("ResetLazy ToDictionaryEx(this IEnumerable ToDictionaryEx(this IEnumerable> collection, IEqualityComparer comparer, string? errorContext = null) where K : notnull { @@ -192,6 +194,25 @@ public static Dictionary ToDictionaryEx(this IEnumerable sourc return result; } + public static FrozenDictionary ToFrozenDictionaryEx(this IEnumerable> collection, string? errorContext = null) + where K : notnull => collection.ToDictionaryEx(errorContext).ToFrozenDictionaryEx(); + + + public static FrozenDictionary ToFrozenDictionaryEx(this IEnumerable> collection, IEqualityComparer comparer, string? errorContext = null) + where K : notnull => collection.ToDictionaryEx(comparer, errorContext).ToFrozenDictionary(); + + public static FrozenDictionary ToFrozenDictionaryEx(this IEnumerable source, Func keySelector, string? errorContext = null) + where K : notnull => source.ToDictionaryEx(keySelector, errorContext).ToFrozenDictionary(); + + public static FrozenDictionary ToFrozenDictionaryEx(this IEnumerable source, Func keySelector, Func elementSelector, string? errorContext = null) + where K : notnull => source.ToDictionaryEx(keySelector, elementSelector, errorContext).ToFrozenDictionary(); + + public static FrozenDictionary ToFrozenDictionaryEx(this IEnumerable source, Func keySelector, IEqualityComparer comparer, string? errorContext = null) + where K : notnull => source.ToDictionaryEx(keySelector, comparer, errorContext).ToFrozenDictionary(); + + public static FrozenDictionary ToFrozenDictionaryEx(this IEnumerable source, Func keySelector, Func elementSelector, IEqualityComparer comparer, string? errorContext = null) + where K : notnull => source.ToDictionaryEx(keySelector, elementSelector, comparer, errorContext).ToFrozenDictionary(); + public static Dictionary JumpDictionary(this IDictionary dictionary, IDictionary other) where K : notnull where Z : notnull diff --git a/Signum.Utilities/MyRandom.cs b/Signum.Utilities/MyRandom.cs index bf988bd144..ae35bae5dd 100644 --- a/Signum.Utilities/MyRandom.cs +++ b/Signum.Utilities/MyRandom.cs @@ -4,14 +4,6 @@ namespace Signum.Utilities; -public static class MyRandom -{ - [ThreadStatic] - static Random? random; - - public static Random Current => random ??= new Random(); -} - public static class RandomExtensions { public static bool NextBool(this Random r) @@ -117,21 +109,6 @@ public static T NextElement(this Random r, IList elements) return elements[r.Next(elements.Count)]; } - public static IEnumerable NextElements(this Random r, IList elements, int numElements) - { - if (numElements * 4 < elements.Count) - return Infinite().Select(a => r.NextElement(elements)).Distinct().Take(numElements); - - return elements.OrderBy(a => r.Next()).Take(numElements); - } - - static IEnumerable Infinite() - { - int i = 0; - while (true) - yield return i++; - } - public static decimal NextDecimal(this Random r, decimal min, decimal max) { return r.NextLong((long)(min * 100L), (long)(max * 100L)) / 100m; diff --git a/Signum/API/ReflectionServer.cs b/Signum/API/ReflectionServer.cs index 7961dd2d0b..1f76706789 100644 --- a/Signum/API/ReflectionServer.cs +++ b/Signum/API/ReflectionServer.cs @@ -8,6 +8,7 @@ using System.Linq; using Signum.Utilities; using System.Collections.Generic; +using System.Collections.Frozen; namespace Signum.API; @@ -31,8 +32,7 @@ public static object GetCurrentValidCulture() public static Dictionary> EntityAssemblies = new Dictionary>(); - public static ResetLazy> TypesByName = new ResetLazy>( - () => GetTypes().ToDictionaryEx(GetTypeName, "Types")); + public static ResetLazy> TypesByName = new (() => GetTypes().ToFrozenDictionaryEx(GetTypeName, "Types")); public static Dictionary> OverrideIsNamespaceAllowed = new Dictionary>(); diff --git a/Signum/Basics/CultureInfoLogic.cs b/Signum/Basics/CultureInfoLogic.cs index c803448af7..14ac982a3b 100644 --- a/Signum/Basics/CultureInfoLogic.cs +++ b/Signum/Basics/CultureInfoLogic.cs @@ -3,6 +3,7 @@ using Signum.Engine.Maps; using Signum.Engine.Sync; using Signum.API; +using System.Collections.Frozen; namespace Signum.Basics; @@ -20,8 +21,8 @@ public static void AssertStarted(SchemaBuilder sb) public static Func CultureInfoModifier = ci => ci; - public static ResetLazy> CultureInfoToEntity = null!; - public static ResetLazy> EntityToCultureInfo = null!; + public static ResetLazy> CultureInfoToEntity = null!; + public static ResetLazy> EntityToCultureInfo = null!; public static void Start(SchemaBuilder sb) { @@ -39,11 +40,11 @@ public static void Start(SchemaBuilder sb) c.NativeName, }); - CultureInfoToEntity = sb.GlobalLazy(() => Database.Query().ToDictionary(ci => ci.Name, + CultureInfoToEntity = sb.GlobalLazy(() => Database.Query().ToFrozenDictionaryEx(ci => ci.Name, ci => ci), invalidateWith: new InvalidateWith(typeof(CultureInfoEntity))); - EntityToCultureInfo = sb.GlobalLazy(() => Database.Query().ToDictionary(ci => ci, + EntityToCultureInfo = sb.GlobalLazy(() => Database.Query().ToFrozenDictionaryEx(ci => ci, ci => CultureInfoModifier(CultureInfo.GetCultureInfo(ci.Name))), invalidateWith: new InvalidateWith(typeof(CultureInfoEntity))); diff --git a/Signum/Basics/PropertyRouteLogic.cs b/Signum/Basics/PropertyRouteLogic.cs index 68f93f595e..af98bd9092 100644 --- a/Signum/Basics/PropertyRouteLogic.cs +++ b/Signum/Basics/PropertyRouteLogic.cs @@ -1,6 +1,7 @@ using Signum.API; using Signum.Engine.Maps; using Signum.Engine.Sync; +using System.Collections.Frozen; namespace Signum.Basics; @@ -10,7 +11,7 @@ public static class PropertyRouteLogic public static bool IsPropertyRoute(this PropertyRouteEntity prdn, PropertyRoute pr) => As.Expression(() => prdn.RootType.Is(pr.RootType.ToTypeEntity()) && prdn.Path == pr.PropertyString()); - public static ResetLazy>> Properties = null!; + public static ResetLazy>> Properties = null!; public static void Start(SchemaBuilder sb) { @@ -28,7 +29,7 @@ public static void Start(SchemaBuilder sb) sb.Schema.Synchronizing += SynchronizeProperties; - Properties = sb.GlobalLazy(() => Database.Query().AgGroupToDictionary(a => a.RootType, gr => gr.ToDictionary(a => a.Path)), + Properties = sb.GlobalLazy(() => Database.Query().AgGroupToDictionary(a => a.RootType, gr => gr.ToFrozenDictionaryEx(a => a.Path)).ToFrozenDictionaryEx(), new InvalidateWith(typeof(PropertyRouteEntity)), Schema.Current.InvalidateMetadata); PropertyRouteEntity.ToPropertyRouteFunc = ToPropertyRouteImplementation; diff --git a/Signum/Basics/QueryLogic.cs b/Signum/Basics/QueryLogic.cs index d2726a4a79..d19043493d 100644 --- a/Signum/Basics/QueryLogic.cs +++ b/Signum/Basics/QueryLogic.cs @@ -2,16 +2,17 @@ using Signum.Utilities.Reflection; using Signum.DynamicQuery.Tokens; using Signum.Engine.Sync; +using System.Collections.Frozen; namespace Signum.Basics; public static class QueryLogic { - static ResetLazy> queryNamesLazy = null!; - public static Dictionary QueryNames => queryNamesLazy.Value; + static ResetLazy> queryNamesLazy = null!; + public static FrozenDictionary QueryNames => queryNamesLazy.Value; - static ResetLazy> queryNameToEntityLazy = null!; - public static Dictionary QueryNameToEntity => queryNameToEntityLazy.Value; + static ResetLazy> queryNameToEntityLazy = null!; + public static FrozenDictionary QueryNameToEntity => queryNameToEntityLazy.Value; public static DynamicQueryContainer Queries { get; } = new DynamicQueryContainer(); public static ExpressionContainer Expressions { get; } = new ExpressionContainer(); @@ -85,7 +86,7 @@ public static void Start(SchemaBuilder sb) q => q.Key, kvp => kvp.Key, (q, kvp) => KeyValuePair.Create(kvp.Value, q), - "caching " + nameof(QueryEntity)).ToDictionary(), + "caching " + nameof(QueryEntity)).ToFrozenDictionaryEx(), new InvalidateWith(typeof(QueryEntity)), Schema.Current.InvalidateMetadata); } @@ -121,9 +122,9 @@ public static object ToQueryName(string queryKey) return QueryNames.TryGetC(queryKey); } - private static Dictionary CreateQueryNames() + private static FrozenDictionary CreateQueryNames() { - return Queries.GetQueryNames().ToDictionaryEx(qn => QueryUtils.GetKey(qn), "queryName"); + return Queries.GetQueryNames().ToFrozenDictionaryEx(qn => QueryUtils.GetKey(qn), "queryName"); } static IEnumerable GenerateQueries() diff --git a/Signum/Basics/SemiSymbolLogic.cs b/Signum/Basics/SemiSymbolLogic.cs index 218d406f41..3160e3485a 100644 --- a/Signum/Basics/SemiSymbolLogic.cs +++ b/Signum/Basics/SemiSymbolLogic.cs @@ -1,12 +1,13 @@ using Signum.Engine.Maps; using Signum.Engine.Sync; +using System.Collections.Frozen; namespace Signum.Basics; public static class SemiSymbolLogic where T : SemiSymbol { - static ResetLazy> lazy = null!; + static ResetLazy> lazy = null!; static Func> getSemiSymbols = null!; [ThreadStatic] @@ -45,7 +46,7 @@ public static void Start(SchemaBuilder sb, Func> getSemiSymbols) "caching " + typeof(T).Name); SemiSymbol.SetFromDatabase(current.ToDictionary(a => a.Key!)); - return result.ToDictionary(a => a.Key!); + return result.ToFrozenDictionaryEx(a => a.Key!); } }, new InvalidateWith(typeof(T)), @@ -117,7 +118,7 @@ private static IEnumerable CreateSemiSymbols() }); } - static Dictionary AssertStarted() + static FrozenDictionary AssertStarted() { if (lazy == null) throw new InvalidOperationException("{0} has not been started. Someone should have called {0}.Start before".FormatWith(typeof(SemiSymbolLogic).TypeName())); diff --git a/Signum/Basics/SymbolLogic.cs b/Signum/Basics/SymbolLogic.cs index 8e9b0ea9e7..7f553a7060 100644 --- a/Signum/Basics/SymbolLogic.cs +++ b/Signum/Basics/SymbolLogic.cs @@ -1,5 +1,6 @@ using Signum.Engine.Maps; using Signum.Engine.Sync; +using System.Collections.Frozen; namespace Signum.Basics; @@ -24,7 +25,7 @@ public static void LoadAll() public static class SymbolLogic where T : Symbol { - static ResetLazy> lazy = null!; + static ResetLazy> lazy = null!; static Func> getSymbols = null!; [ThreadStatic] @@ -72,7 +73,7 @@ public static void Start(SchemaBuilder sb, Func> getSymbols) "caching " + typeof(T).Name); Symbol.SetSymbolIds(current.ToDictionary(a => a.Key, a => a.Id)); - return result.ToDictionary(a => a.Key); + return result.ToFrozenDictionaryEx(a => a.Key); } }, new InvalidateWith(typeof(T)), @@ -138,7 +139,7 @@ static void SymbolLogic_Retrieved(T ident, PostRetrievingContext ctx) }); } - static Dictionary AssertStarted() + static FrozenDictionary AssertStarted() { if (lazy == null) throw new InvalidOperationException("{0} has not been started. Someone should have called {0}.Start before".FormatWith(typeof(SymbolLogic).TypeName())); diff --git a/Signum/Engine/Connection/SqlServerRetry.cs b/Signum/Engine/Connection/SqlServerRetry.cs index eedbf6ec68..0ac25c14e1 100644 --- a/Signum/Engine/Connection/SqlServerRetry.cs +++ b/Signum/Engine/Connection/SqlServerRetry.cs @@ -22,7 +22,7 @@ public static class SqlServerRetry return null; var delta = (Math.Pow(DefaultExponentialBase, currentRetryCount) - 1.0) - * (1.0 + MyRandom.Current.NextDouble() * (DefaultRandomFactor - 1.0)); + * (1.0 + Random.Shared.NextDouble() * (DefaultRandomFactor - 1.0)); var delay = Math.Min( BaseDelay.TotalMilliseconds * delta, diff --git a/Signum/Entities/Reflection/Reflector.cs b/Signum/Entities/Reflection/Reflector.cs index ffe137845d..93bd23fd3a 100644 --- a/Signum/Entities/Reflection/Reflector.cs +++ b/Signum/Entities/Reflection/Reflector.cs @@ -1,6 +1,7 @@ using Signum.Utilities.Reflection; using System.CodeDom.Compiler; using System.Collections.Concurrent; +using System.Collections.Frozen; using System.ComponentModel; using System.Globalization; @@ -43,21 +44,20 @@ static bool DescriptionManager_ShouldLocalizeMemeber(MemberInfo arg) return !arg.HasAttribute() || arg.HasAttribute(); } - static ResetLazy> EnumsInEntities = new ResetLazy>(() => - { - return new HashSet( - from a in AppDomain.CurrentDomain.GetAssemblies() - where a.GetName().Name != "Signum.Analyzer" && a.HasAttribute() - from t in a.GetTypes() - where typeof(IEntity).IsAssignableFrom(t) || typeof(ModifiableEntity).IsAssignableFrom(t) - let da = t.GetCustomAttribute(true) - where da == null || da.Options.IsSet(DescriptionOptions.Members) - from p in t.GetProperties(BindingFlags.Instance | BindingFlags.Public) - where DescriptionManager.OnShouldLocalizeMember(p) - let et = (p.PropertyType.ElementType() ?? p.PropertyType).UnNullify() - where et.IsEnum && et.Assembly.HasAttribute() - select et - ); + static ResetLazy> EnumsInEntities = new(() => + { + return (from a in AppDomain.CurrentDomain.GetAssemblies() + where a.GetName().Name != "Signum.Analyzer" && a.HasAttribute() + from t in a.GetTypes() + where typeof(IEntity).IsAssignableFrom(t) || typeof(ModifiableEntity).IsAssignableFrom(t) + let da = t.GetCustomAttribute(true) + where da == null || da.Options.IsSet(DescriptionOptions.Members) + from p in t.GetProperties(BindingFlags.Instance | BindingFlags.Public) + where DescriptionManager.OnShouldLocalizeMember(p) + let et = (p.PropertyType.ElementType() ?? p.PropertyType).UnNullify() + where et.IsEnum && et.Assembly.HasAttribute() + select et).ToFrozenSet(); + }); static DescriptionOptions? DescriptionManager_IsEnumsInEntities(Type t) diff --git a/Signum/Operations/OperationLogic.cs b/Signum/Operations/OperationLogic.cs index 111d689098..320962d85b 100644 --- a/Signum/Operations/OperationLogic.cs +++ b/Signum/Operations/OperationLogic.cs @@ -5,6 +5,7 @@ using Signum.DynamicQuery.Tokens; using Signum.Security; using Signum.Engine.Sync; +using System.Collections.Frozen; namespace Signum.Operations; @@ -29,12 +30,12 @@ public static IQueryable Logs(this OperationSymbol o) => static Polymorphic> operations = new Polymorphic>(PolymorphicMerger.InheritDictionaryInterfaces, typeof(IEntity)); - static ResetLazy>> operationsFromKey = new ResetLazy>>(() => + static ResetLazy>> operationsFromKey = new ResetLazy>>(() => { return (from t in operations.OverridenTypes from d in operations.GetDefinition(t)!.Keys group t by d into g - select KeyValuePair.Create(g.Key, g.ToList())).ToDictionary(); + select KeyValuePair.Create(g.Key, g.ToList())).ToFrozenDictionaryEx(); }); From f7626dc96d26088d75f826c48bb09ddfb52c2e3d Mon Sep 17 00:00:00 2001 From: Olmo del Corral Cano Date: Thu, 8 Feb 2024 14:19:17 +0100 Subject: [PATCH 4/4] comment in groupToObject and translations --- Signum/React/Globals.ts | 2 +- Signum/Translations/Signum.de.xml | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Signum/React/Globals.ts b/Signum/React/Globals.ts index 51e30732cc..f526f78b13 100644 --- a/Signum/React/Globals.ts +++ b/Signum/React/Globals.ts @@ -21,7 +21,7 @@ declare global { groupBy(this: Array, keySelector: (element: T) => K): { key: K; elements: T[] }[]; groupBy(this: Array, keySelector: (element: T) => K, keyStringifier?: (key: K) => string): { key: K; elements: T[] }[]; groupBy(this: Array, keySelector: (element: T) => K, keyStringifier: ((key: K) => string) | undefined, elementSelector: (element: T) => E): { key: K; elements: E[] }[]; - groupToObject(this: Array, keySelector: (element: T) => string): { [key: string]: T[] }; + groupToObject(this: Array, keySelector: (element: T) => string): { [key: string]: T[] }; // Remove by Object.groupBy when safary supports it https://caniuse.com/?search=Object.groupby groupToObject(this: Array, keySelector: (element: T) => string, elementSelector: (element: T) => E): { [key: string]: E[] }; groupWhen(this: Array, condition: (element: T) => boolean, includeKeyInGroup?: boolean, initialGroup?: boolean): { key: T, elements: T[] }[]; groupWhenChange(this: Array, keySelector: (element: T) => K, keyStringifier?: (key: K) => string): { key: K, elements: T[] }[]; diff --git a/Signum/Translations/Signum.de.xml b/Signum/Translations/Signum.de.xml index b7d4191e75..975e0afc0b 100644 --- a/Signum/Translations/Signum.de.xml +++ b/Signum/Translations/Signum.de.xml @@ -453,16 +453,16 @@ - + - + - + - +