mercredi 1 août 2018

Expression nullable type in reflection

I have method where i generate expression for Entity Framework(i => ids.Contains(i.SomeProperty)).All works Good! But when my property Type is Nullable i have error. How can i get(i => ids.Contains(i.SomeProperty.Value)) or (i => ids.Contains(i.SomeProperty.GetValueOrDefault())) for nullable type

  public static IQueryable Where(this IQueryable source, string propertyName, IEnumerable searchValues)
    {
        //Get target's T 
        var targetType = source.GetType().GetGenericArguments().FirstOrDefault();
        if (targetType == null)
            throw new ArgumentException("Should be IEnumerable<T>", "target");

        //Get searchValues's T
        Type searchValuesType;
        if (searchValues.GetType().IsArray)
            searchValuesType = searchValues.GetType().GetElementType();
        else
            searchValuesType = searchValues.GetType().GetGenericArguments().FirstOrDefault();

        if (searchValuesType == null)
           throw new ArgumentException("Should be IEnumerable<T>", "searchValues");

        //Create a p parameter with the type T of the items in the -> target IEnumerable<T>
        var containsLambdaParameter = Expression.Parameter(targetType, "i");

        //Create a property accessor using the property name -> p.#propertyName#
        var property = Expression.Property(containsLambdaParameter, targetType, propertyName);

        //Create a constant with the -> IEnumerable<T> searchValues
        var searchValuesAsConstant = Expression.Constant(searchValues, searchValues.GetType());

        //Create a method call -> searchValues.Contains(p.Id)
        var containsBody = Expression.Call(typeof(Enumerable), "Contains", new[] { searchValuesType }, searchValuesAsConstant, property);

        //Create a lambda expression with the parameter p -> p => searchValues.Contains(p.Id)
        var containsLambda = Expression.Lambda(containsBody, containsLambdaParameter);

        return source.Provider.CreateQuery(
            Expression.Call(
                typeof(Queryable), "Where",
                new Type[] { source.ElementType },
                source.Expression, Expression.Quote(containsLambda)));

    }





Aucun commentaire:

Enregistrer un commentaire