I have written this generic method to check whether a object has a dependent items or not:
public void ItemDependant<TEntity>(Guid id,
Expression<Func<TEntity, bool>> condition,
Expression<Func<TEntity, string>> select) where TEntity : BaseModel
{
var foundItems = _dbContext.Set<TEntity>().Where(x => x.IsDeleted == false).Where(condition);
var isAny = foundItems.Any();
if (isAny)
throw new Exception($"You must first delete these dependent items: {foundItems.Select(select).ToList().Aggregate((i, j) => i + ", " + j)}");
}
Now in each delete method in our services we call this method this way:
public override void Delete(Guid id)
{
// This entity has only one dependent item (ItemB)
// It means that this entity is being used by ItemB
// So we can't delete it from the database
// We should first delete ItemB
ItemDependant<ItemB>(id, m => m.ItemAId == id, s => s.Title);
base.Delete(id);
}
It works like a charm But I'm wondering if there's a better way for doing this.
Update: There's also another problem with this approach, If the entity has several dependent entities, consumer the API must know about them and add them in order:
public override void Delete(Guid id)
{
ItemDependant<ItemB>(id, m => m.ItemAId == id, s => s.Title);
ItemDependant<ItemC>(id, m => m.ItemAId == id, s => s.Title);
ItemDependant<ItemD>(id, m => m.ItemAId == id, s => s.Title);
ItemDependant<ItemE>(id, m => m.ItemAId == id, s => s.Title);
ItemDependant<ItemF>(id, m => m.ItemAId == id, s => s.Title);
base.Delete(id);
}
One thing that comes in my mind is that, I should have only one ItemDependent(....
call, then this method must inspects all of the dependencies then at the end gives the user several error messages. I think this solution is better, Isn't it?