vendredi 28 juin 2019

Erro when call Contains in Reflection

I pass some params(propertyName and arrayIds) on my service and build Expression via reflection.When i use Entity framework all ok. Some days ago i migrate on EF Core and i get error(Data is Null. This method or property cannot be called on Null values.)

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()*/);

            var res = Expression.Convert(property, searchValuesType);

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

            //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, containsLambda));

        }





Aucun commentaire:

Enregistrer un commentaire