Intentando filtrar en un tipo Nullable utilizando árboles de expresión

He pegado mi aplicación de prueba completa a continuación. Es bastante compacto, así que espero que no sea un problema. Debería poder simplemente cortarlo y pegarlo en una aplicación de consola y ejecutarlo.

Necesito poder filtrar en una o más de las propiedades de los objetos Person, y no sé cuál (es) hasta el tiempo de ejecución. Sé que esto se ha discutido en todas partes y he investigado y también estoy usando herramientas como laPredicateBuilder & Biblioteca dinámica de linq pero la discusión sobre ellos tiende a centrarse más en ordenar y ordenar, y cada uno ha estado luchando con sus propios problemas cuando se enfrentan a tipos de Nullable. Así que pensé que intentaría crear al menos un filtro complementario que pudiera abordar estos escenarios particulares.

En el siguiente ejemplo, estoy tratando de filtrar a los familiares que nacieron después de cierta fecha. La patada es que el campo DateOfBirth en los objetos que se están filtrando es una propiedad DateTime.

El último error que estoy recibiendo es

Ningún operador de coerción se define entre los tipos 'System.String' y 'System.Nullable`1 [System.DateTime]'.

Cuál es el problema. He intentado varios medios diferentes de conversión y conversión, pero con diversos grados de fracaso. En última instancia, esto se aplicará contra una base de datos de EF que también se ha resistido a los métodos de conversión como DateTime.Parse (-).

Cualquier asistencia sería muy apreciada!

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            List<Person> people = new List<Person>();
        people.Add(new Person { FirstName = "Bob", LastName = "Smith", DateOfBirth = DateTime.Parse("1969/01/21"), Weight=207 });
        people.Add(new Person { FirstName = "Lisa", LastName = "Smith", DateOfBirth = DateTime.Parse("1974/05/09") });
        people.Add(new Person { FirstName = "Jane", LastName = "Smith", DateOfBirth = DateTime.Parse("1999/05/09") });
        people.Add(new Person { FirstName = "Lori", LastName = "Jones", DateOfBirth = DateTime.Parse("2002/10/21") });
        people.Add(new Person { FirstName = "Patty", LastName = "Smith", DateOfBirth = DateTime.Parse("2012/03/11") });
        people.Add(new Person { FirstName = "George", LastName = "Smith", DateOfBirth = DateTime.Parse("2013/06/18"), Weight=6 });

            String filterField = "DateOfBirth";
            String filterOper = "<=";
            String filterValue = "2000/01/01";

            var oldFamily = ApplyFilter<Person>(filterField, filterOper, filterValue);

            var query = from p in people.AsQueryable().Where(oldFamily) 
                        select p;

            Console.ReadLine();
        }

        public static Expression<Func<T, bool>> ApplyFilter<T>(String filterField, String filterOper, String filterValue)
        {
            //
            // Get the property that we are attempting to filter on. If it does not exist then throw an exception
            System.Reflection.PropertyInfo prop = typeof(T).GetProperty(filterField);
            if (prop == null)
                throw new MissingMemberException(String.Format("{0} is not a member of {1}", filterField, typeof(T).ToString()));

            Expression convertExpression     = Expression.Convert(Expression.Constant(filterValue), prop.PropertyType);

            ParameterExpression parameter    = Expression.Parameter(prop.PropertyType, filterField);
            ParameterExpression[] parameters = new ParameterExpression[] { parameter };
            BinaryExpression body            = Expression.LessThanOrEqual(parameter, convertExpression);


            Expression<Func<T, bool>> predicate = Expression.Lambda<Func<T, bool>>(body, parameters);


            return predicate;

        }
    }

    public class Person
    {

        public string FirstName { get; set; }
        public string LastName { get; set; }
        public DateTime? DateOfBirth { get; set; }
        string Nickname { get; set; }
        public int? Weight { get; set; }

        public Person() { }
        public Person(string fName, string lName)
        {
            FirstName = fName;
            LastName = lName;
        }
    }
}

Actualización: 2013/02/01

Mi pensamiento entonces fue convertir el tipo Nullabe a su versión de tipo no anulable. Entonces, en este caso, queremos convertir el DateTime <Nullable> a un tipo DateTime simple. Agregué el siguiente bloque de código antes de la llamada a Expression.Convert para determinar y capturar el tipo del valor de Nullable.

//
//
Type propType = prop.PropertyType;
//
// If the property is nullable we need to create the expression using a NON-Nullable version of the type.
// We will get this by parsing the type from the FullName of the type 
if (prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
{
    String typeName = prop.PropertyType.FullName;
    Int32 startIdx  = typeName.IndexOf("[[") + 2;
    Int32 endIdx    = typeName.IndexOf(",", startIdx);
    String type     = typeName.Substring(startIdx, (endIdx-startIdx));
    propType        = Type.GetType(type);
}

Expression convertExpression = Expression.Convert(Expression.Constant(filterValue), propType);

Esto realmente funcionó en la eliminación de Nullable-ness del DateTime, pero resultó en el siguiente error de Coercion. Sigo confundido por esto, ya que pensé que el propósito del método "Expression.Convert" era hacer precisamente esto.

Ningún operador de coerción se define entre los tipos 'System.String' y 'System.DateTime'.

Al presionar, analicé explícitamente el valor de DateTime y lo conecté a la mezcla ...

DateTime dt = DateTime.Parse(filterValue);
Expression convertExpression = Expression.Convert(Expression.Constant(dt), propType);

... lo que dio como resultado una excepción que supera cualquier conocimiento que tenga de Expressions, Lambdas y su tipo relacionado ...

ParameterExpression de tipo 'System.DateTime' no se puede usar para el parámetro delegado de tipo 'ConsoleApplication1.Person'

No estoy seguro de lo que queda por probar.

Respuestas a la pregunta(2)

Su respuesta a la pregunta