Logic Inverse Func <T, bool>
I have fairly complex Entity Framework queries throughout my code base, and I decided to centralize the logic in the models. Basically, create a bunch of controllers with large queries and lots of repeating code in expression trees. So I pulled out parts of these expression trees and moved them to models, which allowed me to do fewer repetitions.
For example, let's say I often have to retrieve models called Entity that are in the Not Deleted state. In my Entity model, I:
public static Func<Entity, bool> IsNotDeleted = e =>
e.Versions != null ?
e.Versions.OrderByDescending(v => v.VersionDate).FirstOrDefault() != null ?
e.Versions.OrderByDescending(v => v.VersionDate).First().ActivityType != VersionActivityType.Delete :
false :
false;
(This is one of the smaller examples, basically just checking valid data before trying to examine that data.)
And using it will look like this:
var entities = EntityRepository.Entities.Where(Entity.IsNotDeleted).Where(...
, , , , . , ? - (, , ):
var entities = EntityRepository.Entities.Where(!Entity.IsDeleted).Where(...
Func<> , IsDeleted IsNotDeleted, . Func<> a bool, , .Where()?
.
public static class Functional
{
public static Func<T, bool> Not<T>(this Func<T, bool> f)
{
return x => !f(x);
}
public static Expression<Func<T, bool>> Not<T>(
this Expression<Func<T, bool>> f)
{
// 1. Break the lambda f apart into its parameters and body.
// 2. Wrap the body expression with a unary not expression (!).
// 3. Construct a new lambda with the modified body.
return Expression.Lambda<Func<T, bool>>(
Expression.Not(f.Body), f.Parameters);
}
}
Entity.IsDeleted.Not() Entity.IsNotDeleted().
, , , Expression<Func<T, bool>> - not Func<T, bool> - - , .
:
Expression<Func<int, bool>> isNegative = x => x < 0;
Expression<Func<int, bool>> isNonNegative = isNegative.Not();