I have a User
class that has 50 navigation properties(one to many). For example:
user>>post , user >> files , ...
In UserServiceLayer
on Delete
action , I want to check all user navigation Properties
before deleting user and If at least one of them is greater than zero (0), there will be no permission to remove.
I have SoftDelete
.
I don't want to use If
blocks to Check All navigation .
Is there a way to check it ? or should I use If
statement.
I would go with something like this:
public class User
{
public int Id { get; set; }
public bool IsDeleted { get; set; }
public virtual ICollection<Post> Posts { get; set; }
public virtual ICollection<File> Files { get; set; }
// etc...
public bool CanDelete()
{
return !Posts.Any() &&
!Files.Any(); // &&
// etc...
}
}
This will keep the logic for determining whether deletion is allowed with the entity, where you can more easily see the properties involved.
You will still need to use an if statement in your UserServiceLayer
, but it will be a very simple if statement.
To make a generic version of this, one way to do it would be to use a custom attribute and an extension method that uses reflection to loop through all properties marked with the attribute.
Define the attribute like this:
[AttributeUsage(AttributeTargets.Property)]
public class MustBeEmptyToDeleteAttribute : Attribute { }
Add the attribute to properties on your entities, like this:
public class User
{
public int Id { get; set; }
public bool IsDeleted { get; set; }
[MustBeEmptyToDelete] public virtual ICollection<Post> Posts { get; set; }
[MustBeEmptyToDelete] public virtual ICollection<File> Files { get; set; }
// etc...
}
Finally, create an extensions class for your entities:
public static class EntityExtensions
{
public static bool CanDelete(this object entity)
{
return entity.GetType().GetProperties()
.Where(x => x.IsDefined(typeof(MustBeEmptyToDeleteAttribute)))
.Select(x => x.GetValue(entity))
.OfType<IEnumerable<object>>()
.All(x => !x.Any());
}
}