I have an expression that uses DbFunctions
class to calculate dates. It works fine for linq-to-entities
but I want to reuse this expression for non-db functionality. Is it possible to detect if expression is evaluated in db context or not and use corresponding implementation? I've seen solution for unit tests which involves mock objects but I need this expression in common business-logic so mocks don't look like a good solution.
Here is my expression:
public static Expression<Func<Transaction, bool>> Expired(int expirationPeriod)
{
return s => s.Status == Status.Created && DbFunctions.AddMinutes(s.UpdateDateUTC, expirationPeriod) < DateTime.UtcNow;
}
I want to be able to do something like this:
public static Expression<Func<Transaction, bool>> Expired(int expirationPeriod)
{
return s => s.Status == Status.Created && MyCustomResolver.AddMinutes(s.UpdateDateUTC, expirationPeriod) < DateTime.UtcNow;
}
where MyCustomResolver
will use either DbFunctions
or DateTime
implementation depending on context.
Finally I used the following approach:
Define a function with DbFunction
attribute. This way it uses corresponding SQL function if used in Linq-to-Entities expression or C# function if executed in non-db context
/// <summary>
/// Utilize functions for both Linq-to-Entities and non-db context
/// </summary>
public static class MyCustomResolver
{
[DbFunction("Edm", "AddMinutes")]
public static DateTime? AddMinutes(DateTime? timeValue, int addValue)
{
return timeValue?.AddMinutes(addValue);
}
}
Build expressions using helper function defined above
public static Expression<Func<Transaction, bool>> Expired(int expirationPeriod)
{
return s => s.Status == Status.Created && MyCustomResolver.AddMinutes(s.UpdateDateUTC, expirationPeriod) < DateTime.UtcNow;
}