/// <summary>
        ///     Finds an entity with the given id. If an entity with the given id
        ///     is being tracked by the context, then it is returned immediately without making a request to the
        ///     database. Otherwise, a query is made to the database for an entity with the given id
        ///     and this entity, if found, is returned. If no entity is found, then
        ///     null is returned. If <paramref name="tracked"/> is <see langword="true"/>,
        ///     then the entity is also attached to the context, so that subsequent calls can
        ///     return the tracked entity without a database roundtrip.
        /// </summary>
        /// <param name="id">The primary id of the entity.</param>
        /// <param name="tracked">
        ///     Whether to put entity to change tracker after it was loaded from database. Note that <c>false</c>
        ///     has no effect if the entity was in change tracker already (it will NOT be detached).
        /// </param>
        /// <returns>The entity found, or null.</returns>
        /// <remarks>
        ///     This method is slightly faster than <see cref="DbSet{TEntity}.Find(object[])"/>
        ///     because the key is known.
        /// </remarks>
        public static TEntity FindById <TEntity, TProperty>(this IIncludableQueryable <TEntity, TProperty> query, int id, bool tracked = true)
            where TEntity : BaseEntity
        {
            if (id == 0)
            {
                return(null);
            }

            return(query.GetDbContext().FindTracked <TEntity>(id) ?? query.ApplyTracking(tracked).SingleOrDefault(x => x.Id == id));
        }
        /// <summary>
        ///     Finds an entity with the given id. If an entity with the given id
        ///     is being tracked by the context, then it is returned immediately without making a request to the
        ///     database. Otherwise, a query is made to the database for an entity with the given id
        ///     and this entity, if found, is returned. If no entity is found, then
        ///     null is returned. If <paramref name="tracked"/> is <see langword="true"/>,
        ///     then the entity is also attached to the context, so that subsequent calls can
        ///     return the tracked entity without a database roundtrip.
        /// </summary>
        /// <param name="id">The primary id of the entity.</param>
        /// <param name="tracked">
        ///     Whether to put entity to change tracker after it was loaded from database. Note that <c>false</c>
        ///     has no effect if the entity was in change tracker already (it will NOT be detached).
        /// </param>
        /// <param name="cancellationToken">A <see cref="CancellationToken" /> to observe while waiting for the task to complete.</param>
        /// <returns>The entity found, or null.</returns>
        /// <remarks>
        ///     This method is slightly faster than <see cref="DbSet{TEntity}.FindAsync(object[], CancellationToken)(object[])"/>
        ///     because the key is known.
        /// </remarks>
        public static ValueTask <TEntity> FindByIdAsync <TEntity, TProperty>(this IIncludableQueryable <TEntity, TProperty> query, int id, bool tracked = true, CancellationToken cancellationToken = default)
            where TEntity : BaseEntity
        {
            if (id == 0)
            {
                return(ValueTask.FromResult((TEntity)null));
            }

            var trackedEntity = query.GetDbContext().FindTracked <TEntity>(id);

            return(trackedEntity != null
                ? new ValueTask <TEntity>(trackedEntity)
                : new ValueTask <TEntity>(
                       query.ApplyTracking(tracked).SingleOrDefaultAsync(x => x.Id == id, cancellationToken)));
        }