diff --git a/src/EntityFramework/Core/Mapping/ViewGeneration/ViewGenerator.cs b/src/EntityFramework/Core/Mapping/ViewGeneration/ViewGenerator.cs index e714a7b..9c8d7f6 100644 --- a/src/EntityFramework/Core/Mapping/ViewGeneration/ViewGenerator.cs +++ b/src/EntityFramework/Core/Mapping/ViewGeneration/ViewGenerator.cs @@ -297,8 +297,9 @@ private ErrorLog GenerateDirectionalViews(ViewTarget viewTarget, CqlIdentifiers // Generate views for each extent in parallel var errorBag = new ConcurrentBag(); var viewBag = new ConcurrentBag>(); + var parallelOptions = new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }; - Parallel.ForEach(extents, extent => + Parallel.ForEach(extents, parallelOptions, extent => { // Each thread uses its own local ViewSet to avoid contention var localViews = new ViewSet(EqualityComparer.Default); @@ -337,12 +338,13 @@ private ErrorLog GenerateDirectionalViews(ViewTarget viewTarget, CqlIdentifiers }); // Merge results on the calling thread (single-threaded, safe) + // Sort by EntitySetBase name for deterministic output ordering var errorLog = new ErrorLog(); foreach (var log in errorBag) { errorLog.Merge(log); } - foreach (var kvp in viewBag) + foreach (var kvp in viewBag.OrderBy(v => v.Key.Name, StringComparer.Ordinal)) { views.Add(kvp.Key, kvp.Value); } @@ -407,6 +409,16 @@ private ErrorLog GenerateDirectionalViewsSequential( errorLog.Merge(exception.ErrorLog); } } + + if (isQueryView) + { + m_config.SetTimeForFinishedActivity(PerfType.QueryViews); + } + else + { + m_config.SetTimeForFinishedActivity(PerfType.UpdateViews); + } + return errorLog; } diff --git a/src/EntityFramework/Core/Mapping/ViewGeneration/ViewgenGatekeeper.cs b/src/EntityFramework/Core/Mapping/ViewGeneration/ViewgenGatekeeper.cs index a419d0a..fc6a30d 100644 --- a/src/EntityFramework/Core/Mapping/ViewGeneration/ViewgenGatekeeper.cs +++ b/src/EntityFramework/Core/Mapping/ViewGeneration/ViewgenGatekeeper.cs @@ -212,8 +212,9 @@ private static ViewGenResults GenerateViewsFromCells( // so they can be processed concurrently with thread-local state. var errorBag = new ConcurrentBag(); var viewBag = new ConcurrentBag>(); + var parallelOptions = new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }; - Parallel.ForEach(cellGroups, cellGroup => + Parallel.ForEach(cellGroups, parallelOptions, cellGroup => { // Each thread gets its own config copy (Stopwatch is not thread-safe) var localConfig = config.CreateCopy(); @@ -254,11 +255,12 @@ private static ViewGenResults GenerateViewsFromCells( }); // Merge results on the calling thread (single-threaded, safe) + // Sort by EntitySetBase name for deterministic output ordering foreach (var log in errorBag) { viewGenResults.AddErrors(log); } - foreach (var kvp in viewBag) + foreach (var kvp in viewBag.OrderBy(v => v.Key.Name, StringComparer.Ordinal)) { viewGenResults.Views.Add(kvp.Key, kvp.Value); }