This simple example builds an expression that compares 2 DateTime values, one of which is a nullable date. In the process it demonstrates conditionally accessing different property values.
class Peep
{
public string FirstName { get; set; }
public DateTime? DOB { get; set; }
}
class Program
{
static void Main( string[] args )
{
var peeps = new List<Peep>
{
new Peep { FirstName = "brad", DOB = DateTime.Now.AddDays( -1 ) },
new Peep { FirstName = "fred", DOB = DateTime.Today },
new Peep { FirstName = "Mr. null date" } };
var constantComparisonExpression = Expression.Constant( DateTime.Today );
var BirthDateParameter = Expression.Parameter( typeof( Peep ), "DOB" );
var birthDateProperty = Expression.Property( BirthDateParameter, "DOB" );
var hasValue = MemberExpression.Property( birthDateProperty, "HasValue" );
var actualValue = MemberExpression.Property( birthDateProperty, "Value" );
var bogusValue = Expression.Constant( DateTime.MinValue );
var condition = Expression.Condition( hasValue, actualValue, bogusValue );
var isEqual = Expression.Equal( condition, constantComparisonExpression );
var finalExpr = Expression.Lambda<Func<Peep, bool>>( isEqual, BirthDateParameter );
// Equivalent of .Where( peep => (peep.DOB.HasValue ? peep.DOB.Value : DateTime.MinValue) == DateTime.Today )
var wrist = peeps.AsQueryable().Where( finalExpr ).ToList();
if ( wrist.Count == 1 )
{
/// Should find fred
Console.WriteLine( wrist[0].FirstName );
}
else
{
Console.WriteLine( "no match" );
}
Console.ReadLine();
}
}
{
public string FirstName { get; set; }
public DateTime? DOB { get; set; }
}
class Program
{
static void Main( string[] args )
{
var peeps = new List<Peep>
{
new Peep { FirstName = "brad", DOB = DateTime.Now.AddDays( -1 ) },
new Peep { FirstName = "fred", DOB = DateTime.Today },
new Peep { FirstName = "Mr. null date" } };
var constantComparisonExpression = Expression.Constant( DateTime.Today );
var BirthDateParameter = Expression.Parameter( typeof( Peep ), "DOB" );
var birthDateProperty = Expression.Property( BirthDateParameter, "DOB" );
var hasValue = MemberExpression.Property( birthDateProperty, "HasValue" );
var actualValue = MemberExpression.Property( birthDateProperty, "Value" );
var bogusValue = Expression.Constant( DateTime.MinValue );
var condition = Expression.Condition( hasValue, actualValue, bogusValue );
var isEqual = Expression.Equal( condition, constantComparisonExpression );
var finalExpr = Expression.Lambda<Func<Peep, bool>>( isEqual, BirthDateParameter );
// Equivalent of .Where( peep => (peep.DOB.HasValue ? peep.DOB.Value : DateTime.MinValue) == DateTime.Today )
var wrist = peeps.AsQueryable().Where( finalExpr ).ToList();
if ( wrist.Count == 1 )
{
/// Should find fred
Console.WriteLine( wrist[0].FirstName );
}
else
{
Console.WriteLine( "no match" );
}
Console.ReadLine();
}
}
If you need to combine multiple expressions, see this. Don't bother searching further, that works.