예제 #1
0
        /// <summary>
        /// Execute a lambda
        /// </summary>
        private object ExecuteLambda(string action, object source, PropertyInfo property, string pathName, PatchOperation op)
        {
            var mi = typeof(QueryExpressionParser).GetGenericMethod("BuildLinqExpression", new Type[] { property.PropertyType.StripGeneric() }, new Type[] { typeof(NameValueCollection) });

            // Does this have a selector?
            var    classAtt = source.GetType().StripGeneric().GetCustomAttribute <ClassifierAttribute>();
            object lambda   = null;

            if (classAtt != null) // The value is complex
            {
                if (op.Value is IdentifiedData)
                {
                    var classProp     = op.GetType().GetRuntimeProperty(classAtt.ClassifierProperty);
                    var classAttValue = classProp.GetValue(op.Value);
                    lambda = mi.Invoke(null, new object[] { NameValueCollection.ParseQueryString($"{op.Path.Replace(pathName, "")}[{classAttValue}]") });
                }
                else
                {
                    lambda = mi.Invoke(null, new object[] { NameValueCollection.ParseQueryString($"{op.Path.Replace(pathName, "")}={op.Value}") });
                }
            }
            else
            {
                lambda = mi.Invoke(null, new object[] { NameValueCollection.ParseQueryString($"{op.Path.Replace(pathName, "")} = {op.Value}") });
            }

            lambda = lambda.GetType().GetRuntimeMethod("Compile", new Type[] { }).Invoke(lambda, new object[] { });
            var filterMethod = typeof(Enumerable).GetGenericMethod(action, new Type[] { property.PropertyType.StripGeneric() }, new Type[] { typeof(IEnumerable <>).MakeGenericType(property.PropertyType.StripGeneric()), lambda.GetType() });

            if (filterMethod == null)
            {
                throw new PatchException($"Cannot locate instance of {action}() method on collection type {source.GetType()} at {op}");
            }
            return(filterMethod.Invoke(null, new object[] { source, lambda }));
        }