private async Task <List <TEntity> > AttachRangeNonExistsAsync(IEnumerable <TEntity> entities, CancellationToken cancellationToken)
        {
            List <TEntity> result = new List <TEntity>();

            foreach (TEntity e in entities)
            {
                TEntity curr = dbSet.Local.FirstOrDefault(e.EqualsAnyId);

                if (curr != null)
                {
                    result.Add(curr);
                }
                else if (Objects.Compare(e.Id, default))
                {
                    if (e is IModelAltenateKey altKey && await GetByUuidAsync(altKey.Uuid, cancellationToken) is TEntity found)
                    {
                        result.Add(found);
                    }
                    else
                    {
                        #if DEBUG
                        throw new InvalidOperationException($"Entity \"{typeof(TEntity).Name}\" is untrackable, " +
                                                            $"thus can not be attached to delete!");
                        #else
                        continue;
                        #endif
                    }
                }
        private IEnumerable <TEntity> AttachRangeNonExists(IEnumerable <TEntity> entities)
        {
            foreach (TEntity e in entities)
            {
                TEntity curr = dbSet.Local.FirstOrDefault(e.EqualsAnyId);

                if (curr != null)
                {
                    yield return(curr);
                }
                else if (Objects.Compare(e.Id, default))
                {
                    if (e is IModelAltenateKey altKey && GetByUuid(altKey.Uuid) is TEntity found)
                    {
                        yield return(found);
                    }
                    else
                    {
                        #if DEBUG
                        throw new InvalidOperationException($"Entity \"{typeof(TEntity).Name}\" is untrackable, " +
                                                            $"thus can not be attached to delete!");
                        #else
                        continue;
                        #endif
                    }
                }
Example #3
0
 /// <summary>
 /// Compare objects id
 /// </summary>
 /// <param name="other"></param>
 /// <returns></returns>
 public virtual bool EqualsId(object other)
 {
     return(other != null &&
            this.GetType() == other.GetType() &&
            other is IModel <ID> otherID &&
            Objects.Compare(this.Id, otherID.Id));
 }
        /// <summary>
        /// Update entity on persistence base.
        /// </summary>
        /// <param name="entity">target entity</param>
        /// <param name="cancellationToken">cancellation token</param>
        /// <returns>task representation with result, updated target entity</returns>
        /// <exception cref="ArgumentNullException">throws when entity is null</exception>
        /// <exception cref="InvalidOperationException">throws when entity is untrackable, does not contains valid id and Uuid.</exception>
        /// <exception cref="DbUpdateException">throws when is not possible update value, value does not exists, for example.</exception>
        public async Task <TEntity> UpdateAsync(TEntity entity, CancellationToken cancellationToken)
        {
            if (entity is null)
            {
                throw new ArgumentNullException(nameof(entity));
            }
            else if (Objects.Compare(entity.Id, default))
            {
                if (entity is IModelAltenateKey altKey)
                {
                    if (Objects.Compare(altKey.Uuid, default))
                    {
                        throw new InvalidOperationException(
                                  $"Entity \"{typeof(TEntity).Name}\" is untrackable, " +
                                  "thus can not be updated! Because it does not contains an Id or Uuid.");
                    }
                }
                else
                {
                    throw new InvalidOperationException(
                              $"Entity \"{typeof(TEntity).Name}\" is untrackable, " +
                              "thus can not be updated! Because it does not contains an Id.");
                }
            }

            //check contains in tracking local dbSet.
            TEntity curr = dbSet.Local
                           .AsParallel()
                           .FirstOrDefault(entity.EqualsAnyId);

            if (curr != null)
            {
                dbContext.Entry(curr)
                .CurrentValues
                .SetValues(entity);
            }
            else if (Objects.Compare(entity.Id, default))
            {
                IModelAltenateKey altKey = entity as IModelAltenateKey ??
                                           throw new InvalidCastException($"Entity \"{typeof(TEntity).Name}\" " +
                                                                          $"does not implements {typeof(IModelAltenateKey).Name}!");

                curr = await dbSet
                       .OfType <IModelAltenateKey>()
                       .Where(t => t.Uuid == altKey.Uuid)
                       .OfType <TEntity>()
                       .OrderBy(t => t.Id)
                       .Take(1)
                       .FirstOrDefaultAsync(cancellationToken);

                if (curr == null)
                {
                    throw new DbUpdateException($"Entity \"{typeof(TEntity).Name}\" " +
                                                $"with Uuid \"{altKey.Uuid}\" does not exist on database!");
                }

                entity.Id = curr.Id;
                dbContext.Entry(curr)
                .CurrentValues
                .SetValues(entity);
            }
            else
            {
                dbContext.Entry(entity).State = EntityState.Modified;
            }

            try
            {
                await dbContext.SaveChangesAsync(cancellationToken);

                if (curr != null)
                {
                    dbContext.Entry(curr).State = EntityState.Detached;
                    dbContext.Entry(entity).CurrentValues.SetValues(curr);
                }

                OnUpdatedCallback(entity);
            }
            finally
            {
                dbContext.Entry(entity).State = EntityState.Detached;
            }

            return(entity);
        }
Example #5
0
 /// <summary>
 /// Compare objects id or uuid
 /// </summary>
 /// <param name="other"></param>
 /// <returns></returns>
 public bool EqualsAnyId(object other)
 {
     return(other != null && this.GetType() == other.GetType() && (
                (other is IModel <ID> otherID && Objects.Compare(this.Id, otherID.Id)) ||
                (other is IModelAltenateKey otherAlt && Objects.Compare(this.Uuid, otherAlt.Uuid))));
 }