diff --git a/Directory.Packages.props b/Directory.Packages.props
index 955d848e..2d469575 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -44,12 +44,12 @@
+
-
diff --git a/src/CommunityToolkit.Datasync.Client/Offline/Operations/PullOperationManager.cs b/src/CommunityToolkit.Datasync.Client/Offline/Operations/PullOperationManager.cs
index 3e09fa24..87549699 100644
--- a/src/CommunityToolkit.Datasync.Client/Offline/Operations/PullOperationManager.cs
+++ b/src/CommunityToolkit.Datasync.Client/Offline/Operations/PullOperationManager.cs
@@ -8,9 +8,12 @@
using CommunityToolkit.Datasync.Client.Query.OData;
using CommunityToolkit.Datasync.Client.Serialization;
using CommunityToolkit.Datasync.Client.Threading;
+using Microsoft.EntityFrameworkCore.ChangeTracking;
+using Microsoft.EntityFrameworkCore.Metadata;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using System.Text.Json;
+using System.Text.Json.Serialization;
namespace CommunityToolkit.Datasync.Client.Offline.Operations;
@@ -42,6 +45,7 @@ internal class PullOperationManager(OfflineDbContext context, IEnumerable
/// The pull options to use.
/// A to observe.
/// The results of the pull operation.
+ [SuppressMessage("Style", "IDE0305:Simplify collection initialization", Justification = "Readability")]
public async Task ExecuteAsync(IEnumerable requests, PullOptions pullOptions, CancellationToken cancellationToken = default)
{
ArgumentValidationException.ThrowIfNotValid(pullOptions, nameof(pullOptions));
@@ -67,7 +71,25 @@ public async Task ExecuteAsync(IEnumerable requests, Pu
}
else if (originalEntity is not null && !metadata.Deleted)
{
- context.Entry(originalEntity).CurrentValues.SetValues(item);
+ // Gather properties marked with [JsonIgnore]
+ HashSet ignoredProps = pullResponse.EntityType
+ .GetProperties(BindingFlags.Public | BindingFlags.Instance)
+ .Where(p => p.IsDefined(typeof(JsonIgnoreAttribute), inherit: true))
+ .Select(p => p.Name)
+ .ToHashSet();
+
+ EntityEntry originalEntry = context.Entry(originalEntity);
+ EntityEntry newEntry = context.Entry(item);
+
+ // Only copy properties that are not marked with [JsonIgnore]
+ foreach (IProperty property in originalEntry.Metadata.GetProperties())
+ {
+ if (!ignoredProps.Contains(property.Name))
+ {
+ originalEntry.Property(property.Name).CurrentValue = newEntry.Property(property.Name).CurrentValue;
+ }
+ }
+
result.IncrementReplacements();
}
@@ -161,12 +183,11 @@ internal async Task> GetPageAsync(HttpClient client, Uri requestUri
object? result = await JsonSerializer.DeserializeAsync(response.ContentStream, pageType, context.JsonSerializerOptions, cancellationToken).ConfigureAwait(false)
?? throw new DatasyncPullException("JSON result is null") { ServiceResponse = response };
- Page