From 8c962fb73b48d4f8fc26d3d6a30e188c323cc0b8 Mon Sep 17 00:00:00 2001 From: Andriy Svyryd Date: Thu, 7 Aug 2025 19:24:56 -0700 Subject: [PATCH] Fix race condition in RuntimeProperty.Sentinel Fixes #36391 --- src/EFCore/Metadata/RuntimeProperty.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/EFCore/Metadata/RuntimeProperty.cs b/src/EFCore/Metadata/RuntimeProperty.cs index 5efc8027355..a9e0eabd1d2 100644 --- a/src/EFCore/Metadata/RuntimeProperty.cs +++ b/src/EFCore/Metadata/RuntimeProperty.cs @@ -22,7 +22,7 @@ public class RuntimeProperty : RuntimePropertyBase, IRuntimeProperty private readonly ValueGenerated _valueGenerated; private readonly bool _isConcurrencyToken; private object? _sentinel; - private object? _sentinelFromProviderValue; + private volatile object? _sentinelFromProviderValue; private readonly PropertySaveBehavior _beforeSaveBehavior; private readonly PropertySaveBehavior _afterSaveBehavior; private readonly Func? _valueGeneratorFactory; @@ -335,11 +335,12 @@ public override object? Sentinel { get { - if (_sentinelFromProviderValue != null) + var providerValue = _sentinelFromProviderValue; + if (providerValue != null) { - var providerValue = _sentinelFromProviderValue; + Interlocked.CompareExchange(ref _sentinel, TypeMapping.Converter!.ConvertFromProvider(providerValue), null); + _sentinelFromProviderValue = null; - _sentinel = TypeMapping.Converter!.ConvertFromProvider(providerValue); } return _sentinel;