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 } }
/// <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); }
/// <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)))); }