Erreur de référence d'objet dans l'assembly DynamicMethods hébergé de manière anonyme

asp.net-web-api c# expression-trees lambda

Question

J'ai le code suivant où je dois implémenter la recherche en texte intégral sur une liste d'objets. J'ai réussi à le faire fonctionner dans une application console. Le problème est lorsque je commence à utiliser cela dans l'application WebAPI. Je reçois un message d'erreur disant que Object reference not set to an instance of an object. et la source est un ensemble Anonymously Hosted DynamicMethods Assembly . Il semble que certaines propriétés du Type T soient nulles et que l'erreur est affichée. Quelqu'un peut-il me dire si ma compréhension est correcte ou non, et si elle est correcte, pouvez-vous également m'aider à comprendre comment supprimer les propriétés null?

public static IEnumerable<T> FullTextSearch<T>(this List<T> list, string searchKey)
        {
            ParameterExpression parameter = Expression.Parameter(typeof(T), "c");
            MethodInfo containsMethod = typeof(string).GetMethod("Contains", new Type[] { typeof(string) });
            var publicProperties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)
                .Where(p => p.PropertyType == typeof(string));
            Expression orExpressions = null;
            foreach (MethodCallExpression callContainsMethod in 
                               from property in publicProperties
                               let myProperty =Expression.Property(parameter, property.Name)
                               select Expression.Call(myProperty, "Contains", null, Expression.Constant(searchKey)))
            {
                if (orExpressions == null)
                {
                    orExpressions = callContainsMethod;
                }
                else
                {
                    orExpressions = Expression.Or(orExpressions, callContainsMethod);
                }
            }

            IQueryable<T> queryable = list.AsQueryable<T>();
            MethodCallExpression whereCallExpression = Expression.Call(
                typeof(Queryable),
                "Where",
                new Type[] { queryable.ElementType },
                queryable.Expression,
                Expression.Lambda<Func<T, bool>>(orExpressions, new ParameterExpression[] { parameter }));
            var results = queryable.Provider.CreateQuery<T>(whereCallExpression).ToList();
            return results;
        }

Réponse acceptée

Ok les gars, je l'ai compris. Voici le code au cas où quelqu'un en aurait besoin.

 public static List<T> FullTextSearch<T>(this List<T> list, string searchKey)
        {
            ParameterExpression parameter = Expression.Parameter(typeof(T), "c");
            MethodInfo containsMethod = typeof(string).GetMethod("Contains", new Type[] { typeof(string) });
            var publicProperties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)
                .Where(p => p.PropertyType == typeof(string));
            Expression orExpressions = null;

            foreach (var callContainsMethod in from property in publicProperties
                                                                let myProperty = Expression.Property(parameter, property.Name)
                                                                let myExpression = Expression.Call(myProperty, "Contains", null, Expression.Constant(searchKey))
                                                                let myNullExp = Expression.Call(typeof(string), (typeof(string).GetMethod("IsNullOrEmpty")).Name, null, myProperty)
                                                                let myNotExp = Expression.Not(myNullExp)
                                                                select new { myExpression, myNotExp })
            {
                var andAlso = Expression.AndAlso(callContainsMethod.myNotExp, callContainsMethod.myExpression);
                if (orExpressions == null)
                {
                    orExpressions = andAlso;
                }
                else
                {
                    orExpressions = Expression.Or(orExpressions, andAlso);
                }
            }

            IQueryable<T> queryable = list.AsQueryable<T>();
            MethodCallExpression whereCallExpression = Expression.Call(
                typeof(Queryable),
                "Where",
                new Type[] { queryable.ElementType },
                queryable.Expression,
                Expression.Lambda<Func<T, bool>>(orExpressions, new ParameterExpression[] { parameter }));
            var results = queryable.Provider.CreateQuery<T>(whereCallExpression).ToList();
            return results;
        }

La seule partie qui a changé est le LINQ où j'obtiens deux expressions qui contiennent l'une pour l'expression "Contient" et l'autre pour l'expression "Not (IsNullOrEmpty)" et également



Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi