/// <summary>
 /// Resolves the deduplicated entity.
 /// </summary>
 /// <param name="entity">The entity to deduplicate.</param>
 /// <param name="primaryKey">The primary key of the entity.</param>
 /// <returns>The deduplicated entity.</returns>
 protected virtual TEntityType Deduplicate(TEntityType entity, object primaryKey)
 {
     if (KeyCache.ContainsKey(primaryKey))
     {
         return(KeyCache[primaryKey]);
     }
     return(entity);
 }
        /// <summary>
        /// Maps a row of data to an entity.
        /// </summary>
        /// <param name="context">A context that contains information used to map Dapper objects.</param>
        /// <returns>The mapped entity, or null if the entity has previously been returned.</returns>
        public virtual TEntityType Map(EntityMapContext context)
        {
            if (PrimaryKey == null)
            {
                throw new InvalidOperationException("PrimaryKey selector is not defined, but is required to use DeduplicatingEntityMapper.");
            }

            // Deduplicate the top object (entity) in the list
            if (context.Items != null &&
                context.Items.Any())
            {
                if (context.Items.First() is TEntityType entity)
                {
                    var previous = entity;

                    var primaryKey = PrimaryKey(entity);
                    if (primaryKey == null)
                    {
                        throw new InvalidOperationException("A null primary key was provided, which results in an unpredictable state.");
                    }

                    // Deduplicate the entity using available information
                    entity = Deduplicate(entity, primaryKey);
                    if (!object.ReferenceEquals(previous, entity))
                    {
                        context.Items = new[] { entity }.Concat(context.Items.Skip(1));
                    }

                    // Map the object
                    var next = Mapper.Map(context);

                    // Return null if we are returning a duplicate object.
                    // Queries can filter out null entries to prevent duplicates.
                    if (ReturnsNullWithDuplicates && KeyCache.ContainsKey(primaryKey))
                    {
                        return(null);
                    }

                    // Cache a reference to the entity
                    KeyCache[primaryKey] = next;

                    // And, return it
                    return(next);
                }
            }

            return(default(TEntityType));
        }