diff --git a/src/CommunityToolkit.Datasync.Client/Offline/OperationsQueue/OperationsQueueManager.cs b/src/CommunityToolkit.Datasync.Client/Offline/OperationsQueue/OperationsQueueManager.cs
index d8ff086..3bab55b 100644
--- a/src/CommunityToolkit.Datasync.Client/Offline/OperationsQueue/OperationsQueueManager.cs
+++ b/src/CommunityToolkit.Datasync.Client/Offline/OperationsQueue/OperationsQueueManager.cs
@@ -8,7 +8,7 @@
using CommunityToolkit.Datasync.Client.Threading;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
-using System.Net;
+using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using System.Text.Json;
@@ -23,7 +23,7 @@ internal class OperationsQueueManager : IOperationsQueueManager
///
/// A lock object for locking against concurrent changes to the queue.
///
- private readonly object pushlock = new();
+ private readonly Lock pushlock = new();
///
/// The map of valid entities that can be synchronized to the service.
@@ -67,24 +67,26 @@ internal OperationsQueueManager(OfflineDbContext context)
/// in scope for the operations queue.
///
/// A list of values.
+ [SuppressMessage("Style", "IDE0305:Simplify collection initialization", Justification = "Readability")]
internal List GetChangedEntitiesInScope()
=> ChangeTracker.Entries()
- .Where(e => e.State is EntityState.Added or EntityState.Modified or EntityState.Deleted)
- .Where(e => this._entityMap.ContainsKey(e.Metadata.Name.AsNullableEmptyString()))
+ .Where(e => e.State is EntityState.Added or EntityState.Modified or EntityState.Deleted && this._entityMap.ContainsKey(e.Metadata.Name.AsNullableEmptyString()))
.ToList();
///
/// Retrieves the list of synchronizable entities that are available for datasync operations.
///
///
- /// An entity is "synchronization ready" if:
- ///
+ /// An entity is "synchronization ready" if:
+ ///
/// * It is a property on this context
/// * The property is public and a .
/// * The property does not have a specified.
/// * The entity type is defined in the model.
/// * The entity type has an Id, UpdatedAt, and Version property (according to the ).
+ ///
///
+ [SuppressMessage("Style", "IDE0305:Simplify collection initialization", Justification = "Readability")]
internal Dictionary GetEntityMap(OfflineDbContext context)
{
ArgumentNullException.ThrowIfNull(context);
@@ -215,11 +217,12 @@ internal IEnumerable GetSynchronizableEntityTypes(IEnumerable allowe
/// Determines if the provided property is a synchronizable property.
///
///
- /// An entity is "synchronization ready" if:
- ///
+ /// An entity is "synchronization ready" if:
+ ///
/// * It is a property on this context
/// * The property is public and a .
/// * The property does not have a specified.
+ ///
///
/// The for the property to check.
/// true if the property is synchronizable; false otherwise.
@@ -243,6 +246,7 @@ internal bool IsSynchronizationEntity(PropertyInfo property)
/// The options to use for this push operation.
/// A to observe.
/// The results of the push operation (asynchronously)
+ [SuppressMessage("Style", "IDE0305:Simplify collection initialization", Justification = "Readability")]
internal async Task PushAsync(IEnumerable entityTypes, PushOptions pushOptions, CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(entityTypes);
@@ -309,6 +313,13 @@ internal async Task PushAsync(IEnumerable entityTypes, PushOpt
if (resolution.Result is ConflictResolutionResult.Client)
{
+ // The client entity is the winner, so we need to update the operation and re-queue it.
+ if (operation.Kind == OperationKind.Add)
+ {
+ // The server has an entity and the client is winning, so we need to replace the entity on the server.
+ operation.Kind = OperationKind.Replace;
+ }
+
operation.Item = JsonSerializer.Serialize(resolution.Entity, entityType, DatasyncSerializer.JsonSerializerOptions);
operation.State = OperationState.Pending;
operation.LastAttempt = DateTimeOffset.UtcNow;