示例#1
0
        public static object GetRouteValues(MethodBase method, object key, MethodMapping methodMapping, TypeMapping typeMapping)
        {
            object routeValues = new
            {
                modelType = typeMapping.ModelType.PartialName(),
                index     = methodMapping.Index
            };

            if (!method.IsConstructor)
            {
                routeValues = new
                {
                    modelType  = typeMapping.ModelType.PartialName(),
                    index      = methodMapping.Index,
                    methodName = methodMapping.MethodName
                };
            }

            if (!method.IsStatic && key != null)
            {
                routeValues = new
                {
                    modelType  = typeMapping.ModelType.PartialName(),
                    index      = methodMapping.Index,
                    methodName = methodMapping.MethodName,
                    key
                };
            }
            return(routeValues);
        }
示例#2
0
        public static MethodInfo SelectMethod(MethodInfo sourceMethod, Type type,
                                              BindingFlags binding = BindingFlags.Public)
        {
            var key = new KeyValuePair <MethodInfo, Type>(sourceMethod, type);

            return(MethodMapping.GetOrAdd(key, k => MatchMethod(k.Key, k.Value, binding)));
        }
示例#3
0
        public override async Task <bool> Evaluate(RulesEngineService rulesEngine)
        {
            MethodMapping methodMapping = rulesEngine.MetaModel.GetMethod(ScriptEntityType.Action, MethodName.ToString());
            var           @class        = methodMapping.Class;

            // Create the object instance
            object @object = rulesEngine.Instantiate(@class);

            // Manually inject the rules Engine context into the object instance
            @class.GetProperty(nameof(ScriptClass.Context)).SetValue(@object, rulesEngine.Context);

            // Generate the method meta-data
            var method = @class.GetMethod(methodMapping.Method.Name);

            List <object> methodParameters = new List <object>();

            method.GetParameters().ToList().ForEach(reflectionParameter =>
            {
                var parameter = Parameters[reflectionParameter.Name];

                if (parameter == null)
                {
                    throw new ApplicationException($"Missing {nameof(Parameter)} {reflectionParameter.Name}");
                }

                methodParameters.Add(parameter.Value);
            });

            // Invoke the method - possibly asynchronously
            bool status = await methodMapping.Method.InvokeAsync(@object, methodParameters.ToArray());

            return(status);
        }
示例#4
0
        private IWithReturnRedirector <TSubject, TProxy, TProxyResult, TSubjectResult> SetMethod <TProxyResult, TProxyParam, TSubjectParam>
            (Expression <Func <TProxy, TProxyResult> > invocation,
            Func <TProxyParam, TSubjectParam> with = null)
        {
            MethodMapping             mapping = GetMemberAccessInfo(invocation);
            Func <object[], object[]> transform;

            if (with != null)
            {
                transform = (arguments) => new object[] { with((TProxyParam)arguments[0]) };
            }
            else
            {
                transform = (args) => args;
            }

            var returnRedirector = new ProxyReturnRedirector <TSubject, TProxy, TProxyResult, TSubjectResult>()
            {
                generator                = this.generator,
                map                      = this.map,
                pendingMapping           = mapping,
                accesor                  = this.accesor,
                setter                   = this.setter,
                methodCall               = this.methodCall,
                ParametersTransformation = transform
            };

            // That's about it. (leave a pending mapping)
            // Make a new Proxy ReturnRedirector with previous data.
            return(returnRedirector);
        }
示例#5
0
 public MethodDescriptor(MethodMapping mapping, ActionDescriptor actionDescriptor)
     : base(mapping.Name)
 {
     Method         = mapping.Method;
     Index          = mapping.Index;
     AttributeArray = Method.GetCustomAttributes(true).OfType <Attribute>().ToArray();
     parameters.AddRange(Method.GetParameters().Select(info => new ReflectedParameterDescriptor(info, actionDescriptor)));
 }
示例#6
0
        private static void WriteMethod(StreamWriter writer, MethodMapping method, bool isStatic = false)
        {
            var removeId = isStatic ? ", id : null" : string.Empty;

            writer.Write("'{0}': {{ method:'POST', params : {{ methodName:'{1}' {2} ", ToCamelCase(method.MethodName), method.MethodName, removeId);

            //foreach (var parameter in method.Parameters)
            //{
            //	writer.Write(", {0}:'@{0}' ", parameter.Name);
            //}

            writer.WriteLine(" } }, ");
        }
        /// <summary>
        /// Map methods to actions.
        /// </summary>
        /// <param name="info">Method to inspect.</param>
        /// <remarks>Goes through all custom action attributes to check which HTTP methods
        /// the action is valid for.</remarks>
        /// <exception cref="ActionMappingException">Mapping collision. Do not both suffix methods with a verb and use ValidFor attribute.</exception>
        private void MapMethod(MethodInfo info)
        {
            string verb;
            string methodName = info.Name;
            bool   isFound    = TryGetVerb(ref methodName, out verb);

            MethodMapping mapping;

            if (!_methods.TryGetValue(methodName.ToLower(), out mapping))
            {
                mapping = new MethodMapping();
                _methods.Add(methodName.ToLower(), mapping);
            }

            // specified a verb
            if (isFound)
            {
                _logger.Trace("Mapped " + _uri + "." + methodName.ToLower() + " to " + verb);
                mapping.IsMethodsSpecified = true;
                mapping.Add(verb, info);
            }


            // Check if method is valid only for a few verbs
            foreach (object customAttribute in info.GetCustomAttributes(false))
            {
                var attr = customAttribute as ValidForAttribute;
                if (attr == null)
                {
                    continue;
                }
                if (isFound)
                {
                    throw new ActionMappingException(
                              "Mapping collision. Do not both suffix methods with a verb and use ValidFor attribute.");
                }

                mapping.IsMethodsSpecified = true;
                foreach (string method in attr.Methods)
                {
                    _logger.Trace("Mapped " + _uri + "." + methodName.ToLower() + " to " + method);
                    mapping.Add(method, info);
                }
            }

            if (!mapping.IsMethodsSpecified)
            {
                _logger.Trace("Mapped " + _uri + "." + methodName.ToLower() + " to ALL verbs");
                mapping.Add(verb, info);
            }
        }
示例#8
0
        public IWithGetOrSetRedirector <TSubject, TProxy, TSubjectResult, TProxyResult> Property <TProxyResult>(Expression <Func <TProxy, TProxyResult> > invocation)
        {
            MethodMapping mapping            = GetMemberAccessInfo(invocation);
            var           propertyRedirector = new PropertyRedirector <TSubject, TProxy, TSubjectResult, TProxyResult>()
            {
                generator      = this.generator,
                map            = this.map,
                setter         = this.setter,
                accesor        = this.accesor,
                pendingMapping = mapping
            };

            return(propertyRedirector);
        }
        public MethodCallExpressionResolve(ExpressionParameter parameter) : base(parameter)
        {
            var    express             = base.Expression as MethodCallExpression;
            var    isLeft              = parameter.IsLeft;
            string methodName          = express.Method.Name;
            var    isValidNativeMethod = MethodMapping.ContainsKey(methodName) && express.Method.DeclaringType.Namespace == ("System");
            List <MethodCallExpressionArgs> appendArgs = null;

            if (MethodTimeMapping.ContainsKey(methodName))
            {
                appendArgs = new List <MethodCallExpressionArgs>();
                var    dateType     = MethodTimeMapping[methodName];
                string paramterName = this.Context.SqlParameterKeyWord + ExpressionConst.Const + this.Context.ParameterIndex;
                appendArgs.Add(new MethodCallExpressionArgs()
                {
                    IsMember = false, MemberName = paramterName, MemberValue = dateType
                });
                this.Context.Parameters.Add(new SugarParameter(paramterName, dateType.ToString()));
                this.Context.ParameterIndex++;
                methodName          = "DateAdd";
                isValidNativeMethod = true;
            }
            else if (methodName == "get_Item")
            {
                string paramterName = this.Context.SqlParameterKeyWord + ExpressionConst.Const + this.Context.ParameterIndex;
                this.Context.Parameters.Add(new SugarParameter(paramterName, ExpressionTool.DynamicInvoke(express)));
                this.Context.Result.Append(string.Format(" {0} ", paramterName));
                this.Context.ParameterIndex++;
                return;
            }
            else if (methodName == "NewGuid")
            {
                this.Context.Result.Append(this.Context.DbMehtods.GuidNew());
                return;
            }
            if (!isValidNativeMethod && express.Method.DeclaringType.Namespace.IsIn("System.Linq", "System.Collections.Generic") && methodName == "Contains")
            {
                methodName          = "ContainsArray";
                isValidNativeMethod = true;
            }
            if (isValidNativeMethod)
            {
                NativeExtensionMethod(parameter, express, isLeft, MethodMapping[methodName], appendArgs);
            }
            else
            {
                SqlFuncMethod(parameter, express, isLeft);
            }
        }
示例#10
0
        public new static ConditionExpression Parse(Metamodel metaModel, string expressionText)
        {
            var groupedMatches = Syntax.Condition.Matches(expressionText)[0].Groups;

            // e.g - Func.GreaterThan:Int32:1,Logic.IsTrue:Boolean:True
            string methodNameText = groupedMatches[1].Value;
            string parametersText = groupedMatches[5].Value;

            MethodMapping methodMapping = metaModel.Conditions[methodNameText];

            MethodNameExpression methodNameExpression = MethodNameExpression.Parse(metaModel, methodNameText);
            Parameters           parameters           = Parameters.Parse(metaModel, methodMapping.EnumParameterTypes, parametersText);

            return(new ConditionExpression(methodNameExpression, parameters));
        }
示例#11
0
        public static ActionExpression Parse(Metamodel metaModel, string expressionText)
        {
            Match match = FullMatch(Syntax.Action, expressionText);

            if (match == null)
            {
                throw new Exception($"Unmatched {nameof(ActionExpression)} {expressionText}");
            }
            ;

            MethodNameExpression methodNameExpression = MethodNameExpression.Parse(metaModel, match.Groups[1].Value);
            MethodMapping        methodMapping        = metaModel.Actions[methodNameExpression.ToString()];
            Parameters           parameters           = Parameters.Parse(metaModel, methodMapping.EnumParameterTypes, match.Groups[5].Value);

            return(new ActionExpression(methodNameExpression, parameters));
        }
示例#12
0
        /// <summary>
        /// Specifies how to transform the resulting call of the subject to the proxy result.
        /// </summary>
        /// <param name="transform">The transform.</param>
        /// <returns>The proxy build object</returns>
        /// <remarks>TODO: Refine documentation</remarks>
        public IWithSetRedirector <TSubject, TProxy, TSubjectResult, TProxyResult> WithGetter(Func <TSubjectResult, TProxyResult> transform)
        {
            var mapping = new MethodMapping()
            {
                Name    = "get_" + this.pendingMapping.Name,
                Subject = (subject, parameters) =>
                {
                    TSubjectResult result = this.accesor(((TSubject)subject));
                    return(transform(result));
                },
                ArgumentTypes        = Type.EmptyTypes,
                GenericArgumentTypes = Type.EmptyTypes
            };

            this.map.Add(mapping);

            return(this);
        }
示例#13
0
        public void TestIfANotFoundPropertyCanBeRedirected()
        {
            // Arrange
            var          generator = new ProxyGenerator();
            InterfaceMap map       = new InterfaceMap()
            {
                Subject = new MoreProperties()
                {
                    UnmappedProperty = "5"
                }
            };

            MethodMapping mapping = new MethodMapping()
            {
                Subject = (proxied, parameters) =>
                {
                    MoreProperties subject = (MoreProperties)proxied;
                    return(int.Parse(subject.UnmappedProperty));
                },
                Name                 = "get_ExtraGetProperty",
                ArgumentTypes        = Type.EmptyTypes,
                GenericArgumentTypes = Type.EmptyTypes
            };

            map.Add(mapping);


            MatchingInterceptor <IMoreProperties> interceptor = new MatchingInterceptor <IMoreProperties>(map);

            int expected = 5;
            int actual   = 0;

            // Act
            IMoreProperties proxy  = generator.CreateInterfaceProxyWithoutTarget <IMoreProperties>(interceptor);
            TestDelegate    getter = () =>
            {
                actual = proxy.ExtraGetProperty;
            };

            // Assert
            Assert.That(proxy, Is.Not.Null);
            Assert.That(getter, Throws.Nothing);
            Assert.That(actual, Is.EqualTo(expected));
        }
示例#14
0
        /// <summary>
        /// Sets the function for transforming from the proxy result type to the subject result type
        /// </summary>
        /// <param name="transform">The transform.</param>
        /// <returns>The proxy builder object</returns>
        /// <remarks>TODO: Refine documentation</remarks>
        public IWithGetRedirector <TSubject, TProxy, TSubjectResult, TProxyResult> WithSetter(
            Func <TProxyResult, TSubjectResult> transform)
        {
            var mapping = new MethodMapping()
            {
                Name                 = "set_" + this.pendingMapping.Name,
                ArgumentTypes        = new Type[] { typeof(TProxyResult) },
                GenericArgumentTypes = Type.EmptyTypes,
                Subject              = (subject, parameters) =>
                {
                    TProxyResult   argument = (TProxyResult)(parameters[0]);
                    TSubjectResult result   = transform(argument);
                    TSubject       source   = (TSubject)subject;
                    this.setter(source, result);
                    return(null);
                }
            };

            this.map.Add(mapping);

            return(this);
        }
        /// <summary>
        /// Gets the expression invocation info.
        /// </summary>
        /// <typeparam name="TProxy">The type of the Proxy.</typeparam>
        /// <typeparam name="TResult">The type of the Result.</typeparam>
        /// <param name="invocation">The invocation expression.</param>
        /// <returns>The filled in MethodMapping with pending Subject</returns>
        /// <exception cref="System.InvalidOperationException">If the invocation is not a method or property call</exception>
        protected static MethodMapping GetMemberAccessInfo <TProxy, TResult>(Expression <Func <TProxy, TResult> > invocation)
            where TProxy : class
        {
            MethodMapping info       = new MethodMapping();
            Expression    expression = invocation.Body;

            switch (expression.NodeType)
            {
            case ExpressionType.MemberAccess:
            {
                MemberExpression specificExpression = (MemberExpression)invocation.Body;
                MemberInfo       member             = specificExpression.Member;
                if (member.MemberType == MemberTypes.Property)
                {
                    info.ArgumentTypes        = Type.EmptyTypes;
                    info.GenericArgumentTypes = Type.EmptyTypes;
                    info.Name = member.Name;
                }
            }
            break;

            case ExpressionType.Call:
            {
                MethodCallExpression specificExpression = (MethodCallExpression)invocation.Body;
                MethodInfo           method             = specificExpression.Method;

                info.ArgumentTypes        = GetArgumentTypes(method);
                info.GenericArgumentTypes = GetGenericArgumentTypes(method);
                info.Name = method.Name;
            }
            break;

            default:
                throw new InvalidOperationException(string.Format("Cant redirect expression with a node: {0}", invocation.Body.NodeType));
            }

            return(info);
        }
示例#16
0
        protected override Expression VisitNew(NewExpression nex)
        {
            nex = base.VisitNew(nex) as NewExpression;
            var lambda = MethodMapping.ConvertMember(nex.Constructor);

            if (lambda != null)
            {
                var ef    = lambda.Body.Unwrap();
                var parms = new Dictionary <string, ParameterMapping>(lambda.Parameters.Count);
                var pn    = 0;

                foreach (var p in lambda.Parameters)
                {
                    parms.Add(p.Name, new ParameterMapping(pn++, p.Type));
                }

                return(ef.Convert(wpi =>
                {
                    if (wpi.NodeType == ExpressionType.Parameter)
                    {
                        var pe = (ParameterExpression)wpi;
                        var n = parms[pe.Name];
                        var tmp = nex.Arguments[n.Index];
                        if (tmp.Type != n.Type)
                        {
                            return Expression.Convert(tmp, n.Type);
                        }
                        return tmp;
                    }

                    return wpi;
                }));
            }

            return(nex);
        }
        private void Update(MemberInitExpression expression, ExpressionParameter parameter)
        {
            int i = 0;

            foreach (MemberBinding binding in expression.Bindings)
            {
                ++i;
                if (binding.BindingType != MemberBindingType.Assignment)
                {
                    throw new NotSupportedException();
                }
                MemberAssignment memberAssignment = (MemberAssignment)binding;
                var type       = expression.Type;
                var memberName = this.Context.GetDbColumnName(type.Name, memberAssignment.Member.Name);
                var item       = memberAssignment.Expression;

                //Column IsJson Handler
                if (memberAssignment.Member.CustomAttributes != null)
                {
                    var customAttribute = memberAssignment.Member.GetCustomAttribute <SugarColumn>();

                    if (customAttribute?.IsJson ?? false)
                    {
                        var paramterValue = ExpressionTool.DynamicInvoke(item);
                        var parameterName = AppendParameter(new SerializeService().SerializeObject(paramterValue));
                        this.Context.Result.Append(base.Context.GetEqString(memberName, parameterName));

                        continue;
                    }
                }

                if ((item is MemberExpression) && ((MemberExpression)item).Expression == null)
                {
                    var    paramterValue = ExpressionTool.DynamicInvoke(item);
                    string parameterName = AppendParameter(paramterValue);
                    this.Context.Result.Append(base.Context.GetEqString(memberName, parameterName));
                }
                else if (IsNotMember(item))
                {
                    if (base.Context.Result.IsLockCurrentParameter == false)
                    {
                        base.Context.Result.CurrentParameter       = parameter;
                        base.Context.Result.IsLockCurrentParameter = true;
                        parameter.IsAppendTempDate();
                        base.Expression = item;
                        base.Expression = (item as UnaryExpression).Operand;
                        base.Start();
                        parameter.IsAppendResult();
                        var result = this.Context.DbMehtods.IIF(new MethodCallExpressionModel()
                        {
                            Args = new List <MethodCallExpressionArgs>()
                            {
                                new MethodCallExpressionArgs()
                                {
                                    IsMember = true, MemberName = parameter.CommonTempData.ObjToString() + "=1"
                                },
                                new MethodCallExpressionArgs()
                                {
                                    IsMember = true, MemberName = AppendParameter(0)
                                },
                                new MethodCallExpressionArgs()
                                {
                                    IsMember = true, MemberName = AppendParameter(1)
                                }
                            }
                        });
                        parameter.Context.Result.Append(base.Context.GetEqString(memberName, result));
                        base.Context.Result.CurrentParameter = null;
                    }
                }
                else if (IsNotParameter(item))
                {
                    try
                    {
                        parameter.Context.Result.Append(base.Context.GetEqString(memberName, AppendParameter(ExpressionTool.DynamicInvoke(item).ObjToBool())));
                    }
                    catch
                    {
                        throw new NotSupportedException(item.ToString());
                    }
                }
                else if (IsMethod(item))
                {
                    if (item is UnaryExpression)
                    {
                        item = (item as UnaryExpression).Operand;
                    }
                    var callMethod = item as MethodCallExpression;
                    if (MethodTimeMapping.Any(it => it.Key == callMethod.Method.Name) || MethodMapping.Any(it => it.Key == callMethod.Method.Name) || IsExtMethod(callMethod.Method.Name) || IsSubMethod(callMethod) || callMethod.Method.DeclaringType.FullName.StartsWith(UtilConstants.AssemblyName + UtilConstants.Dot))
                    {
                        MethodCall(parameter, memberName, item);
                    }
                    else
                    {
                        var    paramterValue = ExpressionTool.DynamicInvoke(item);
                        string parameterName = AppendParameter(paramterValue);
                        this.Context.Result.Append(base.Context.GetEqString(memberName, parameterName));
                    }
                }
                else if (IsConst(item) && IsConvert(item) && UtilMethods.IsNullable(item.Type) && UtilMethods.GetUnderType(item.Type) == UtilConstants.BoolType)
                {
                    item = (item as UnaryExpression).Operand;
                    parameter.Context.Result.Append(base.Context.GetEqString(memberName, GetNewExpressionValue(item)));
                }
                else if (IsConst(item))
                {
                    base.Expression = item;
                    base.Start();
                    string parameterName = this.Context.SqlParameterKeyWord + ExpressionConst.Const + this.Context.ParameterIndex;
                    parameter.Context.Result.Append(base.Context.GetEqString(memberName, parameterName));
                    var addItem  = new SugarParameter(parameterName, parameter.CommonTempData);
                    var dataType = UtilMethods.GetUnderType(item.Type);
                    if (addItem.Value == null && dataType == UtilConstants.DateType)
                    {
                        addItem.DbType = System.Data.DbType.Date;
                    }
                    this.Context.Parameters.Add(addItem);
                    this.Context.ParameterIndex++;
                }
                else if (item is MemberExpression)
                {
                    if (base.Context.Result.IsLockCurrentParameter == false)
                    {
                        base.Context.Result.CurrentParameter       = parameter;
                        base.Context.Result.IsLockCurrentParameter = true;
                        parameter.IsAppendTempDate();
                        base.Expression = item;
                        base.Start();
                        parameter.IsAppendResult();
                        parameter.Context.Result.Append(base.Context.GetEqString(memberName, parameter.CommonTempData.ObjToString()));
                        base.Context.Result.CurrentParameter = null;
                    }
                }
                else if (item is BinaryExpression)
                {
                    var result = GetNewExpressionValue(item);
                    if (result.HasValue())
                    {
                        result = result.Replace(",", UtilConstants.ReplaceCommaKey);
                    }
                    this.Context.Result.Append(base.Context.GetEqString(memberName, result));
                }
                else if (item is MemberInitExpression)
                {
                    try
                    {
                        var value         = ExpressionTool.DynamicInvoke(item);
                        var parameterName = AppendParameter(value);
                        parameter.Context.Result.Append(base.Context.GetEqString(memberName, parameterName));
                    }
                    catch (Exception ex)
                    {
                        throw new NotSupportedException("Not Supported " + item.ToString() + " " + ex.Message);
                    }
                }
                else if (item is NewExpression)
                {
                    try
                    {
                        var value         = ExpressionTool.DynamicInvoke(item);
                        var parameterName = AppendParameter(value);
                        parameter.Context.Result.Append(base.Context.GetEqString(memberName, parameterName));
                    }
                    catch (Exception ex)
                    {
                        throw new NotSupportedException("Not Supported " + item.ToString() + " " + ex.Message);
                    }
                }
                else if (item is ConditionalExpression)
                {
                    var result = GetNewExpressionValue(item);
                    this.Context.Result.Append(base.Context.GetEqString(memberName, result));
                }
            }
        }
示例#18
0
        private void Update(MemberInitExpression expression, ExpressionParameter parameter)
        {
            int i = 0;

            foreach (MemberBinding binding in expression.Bindings)
            {
                ++i;
                if (binding.BindingType != MemberBindingType.Assignment)
                {
                    throw new NotSupportedException();
                }
                MemberAssignment memberAssignment = (MemberAssignment)binding;
                var type       = expression.Type;
                var memberName = this.Context.GetDbColumnName(type.Name, memberAssignment.Member.Name);
                var item       = memberAssignment.Expression;
                if ((item is MemberExpression) && ((MemberExpression)item).Expression == null)
                {
                    var    paramterValue = ExpressionTool.DynamicInvoke(item);
                    string parameterName = AppendParameter(paramterValue);
                    this.Context.Result.Append(base.Context.GetEqString(memberName, parameterName));
                }
                else if (IsMethod(item))
                {
                    if (item is UnaryExpression)
                    {
                        item = (item as UnaryExpression).Operand;
                    }
                    var callMethod = item as MethodCallExpression;
                    if (MethodTimeMapping.Any(it => it.Key == callMethod.Method.Name) || MethodMapping.Any(it => it.Key == callMethod.Method.Name) || IsExtMethod(callMethod.Method.Name) || IsSubMethod(callMethod) || callMethod.Method.DeclaringType.FullName.StartsWith(UtilConstants.AssemblyName + UtilConstants.Dot))
                    {
                        MethodCall(parameter, memberName, item);
                    }
                    else
                    {
                        var    paramterValue = ExpressionTool.DynamicInvoke(item);
                        string parameterName = AppendParameter(paramterValue);
                        this.Context.Result.Append(base.Context.GetEqString(memberName, parameterName));
                    }
                }
                else if (IsConst(item))
                {
                    base.Expression = item;
                    base.Start();
                    string parameterName = this.Context.SqlParameterKeyWord + ExpressionConst.Const + this.Context.ParameterIndex;
                    parameter.Context.Result.Append(base.Context.GetEqString(memberName, parameterName));
                    this.Context.Parameters.Add(new SugarParameter(parameterName, parameter.CommonTempData));
                    this.Context.ParameterIndex++;
                }
                else if (item is MemberExpression)
                {
                    if (base.Context.Result.IsLockCurrentParameter == false)
                    {
                        base.Context.Result.CurrentParameter       = parameter;
                        base.Context.Result.IsLockCurrentParameter = true;
                        parameter.IsAppendTempDate();
                        base.Expression = item;
                        base.Start();
                        parameter.IsAppendResult();
                        parameter.Context.Result.Append(base.Context.GetEqString(memberName, parameter.CommonTempData.ObjToString()));
                        base.Context.Result.CurrentParameter = null;
                    }
                }
                else if (item is BinaryExpression)
                {
                    var result = GetNewExpressionValue(item);
                    this.Context.Result.Append(base.Context.GetEqString(memberName, result));
                }
            }
        }
示例#19
0
        public MethodCallExpressionResolve(ExpressionParameter parameter) : base(parameter)
        {
            var    express             = base.Expression as MethodCallExpression;
            var    isLeft              = parameter.IsLeft;
            string methodName          = express.Method.Name;
            var    isValidNativeMethod = MethodMapping.ContainsKey(methodName) && express.Method.DeclaringType.Namespace == ("System");
            List <MethodCallExpressionArgs> appendArgs = null;

            if (MethodTimeMapping.ContainsKey(methodName))
            {
                appendArgs = new List <MethodCallExpressionArgs>();
                var    dateType     = MethodTimeMapping[methodName];
                string paramterName = this.Context.SqlParameterKeyWord + ExpressionConst.Const + this.Context.ParameterIndex;
                appendArgs.Add(new MethodCallExpressionArgs()
                {
                    IsMember = false, MemberName = paramterName, MemberValue = dateType
                });
                this.Context.Parameters.Add(new SugarParameter(paramterName, dateType.ToString()));
                this.Context.ParameterIndex++;
                methodName          = "DateAdd";
                isValidNativeMethod = true;
            }
            else if (methodName == "get_Item")
            {
                string paramterName = this.Context.SqlParameterKeyWord + ExpressionConst.Const + this.Context.ParameterIndex;
                this.Context.Parameters.Add(new SugarParameter(paramterName, ExpressionTool.DynamicInvoke(express)));
                this.Context.Result.Append(string.Format(" {0} ", paramterName));
                this.Context.ParameterIndex++;
                return;
            }
            else if (methodName == "NewGuid")
            {
                this.Context.Result.Append(this.Context.DbMehtods.GuidNew());
                return;
            }
            else if (IsSubMethod(express, methodName))
            {
                //Check.Exception(!(parameter.BaseExpression is BinaryExpression), "Current expressions are not supported");
                SubResolve subResolve = new SubResolve(express, this.Context, parameter.OppsiteExpression);
                var        appendSql  = subResolve.GetSql();
                if (this.Context.ResolveType.IsIn(ResolveExpressType.SelectMultiple, ResolveExpressType.SelectSingle))
                {
                    parameter.BaseParameter.CommonTempData = appendSql;
                }
                else
                {
                    base.AppendValue(parameter, isLeft, appendSql);
                }
                return;
            }
            if (IsContainsArray(express, methodName, isValidNativeMethod))
            {
                methodName          = "ContainsArray";
                isValidNativeMethod = true;
            }
            if (isValidNativeMethod)
            {
                NativeExtensionMethod(parameter, express, isLeft, MethodMapping[methodName], appendArgs);
            }
            else
            {
                SqlFuncMethod(parameter, express, isLeft);
            }
        }
示例#20
0
        protected override Expression VisitMemberAccess(MemberExpression m)
        {
            m = base.VisitMemberAccess(m) as MemberExpression;
            var expression = m.Expression;

            var l = MethodMapping.ConvertMember(m.Member);

            if (l != null)
            {
                var body = l.Body.Unwrap();
                var expr = body.Convert(wpi => wpi.NodeType == ExpressionType.Parameter ? expression : wpi);

                if (expr.Type != m.Type)
                {
                    expr = Expression.Convert(expr, m.Type);
                }

                return(expr);
            }

            if (m.Member.DeclaringType == typeof(TimeSpan))
            {
                switch (expression.NodeType)
                {
                case ExpressionType.Subtract:
                case ExpressionType.SubtractChecked:

                    DateParts datePart;

                    switch (m.Member.Name)
                    {
                    case "TotalMilliseconds":
                    case "TotalSeconds":
                    case "TotalMinutes":
                    case "TotalHours":
                    case "TotalDays":
                        throw new NotSupportedException(string.Format("The member access '{0}' is not supported", m.Member));

                    case "Milliseconds": datePart = DateParts.Millisecond; break;

                    case "Seconds": datePart = DateParts.Second; break;

                    case "Minutes": datePart = DateParts.Minute; break;

                    case "Hours": datePart = DateParts.Hour; break;

                    case "Days": datePart = DateParts.Day; break;

                    default: return(m);
                    }

                    var ex = (BinaryExpression)expression;

                    var call = Expression.Call(
                        DateDiffMethod,
                        Expression.Constant(datePart),
                        Expression.Convert(ex.Left, typeof(DateTime)),
                        Expression.Convert(ex.Right, typeof(DateTime)));

                    return(Visit(call));
                }
            }

            return(m);
        }
示例#21
0
        protected override Expression VisitMethodCall(MethodCallExpression m)
        {
            m = base.VisitMethodCall(m) as MethodCallExpression;

            var lambda = MethodMapping.ConvertMember(m.Method);

            if (lambda != null)
            {
                var ef    = lambda.Body.Unwrap();
                var parms = new Dictionary <string, ParameterMapping>(lambda.Parameters.Count);
                var pn    = m.Method.IsStatic ? 0 : -1;

                foreach (var p in lambda.Parameters)
                {
                    parms.Add(p.Name, new ParameterMapping(pn++, p.Type));
                }

                var pie = ef.Convert(wpi =>
                {
                    if (wpi.NodeType == ExpressionType.Parameter)
                    {
                        ParameterMapping n;
                        if (parms.TryGetValue(((ParameterExpression)wpi).Name, out n))
                        {
                            var tmp = n.Index < 0 ? m.Object : m.Arguments[n.Index];
                            if (tmp.Type != n.Type)
                            {
                                return(Expression.Convert(tmp, n.Type));
                            }
                            return(tmp);
                        }
                    }

                    return(wpi);
                });

                if (m.Method.ReturnType != pie.Type)
                {
                    pie = Expression.Convert(pie, m.Method.ReturnType);
                }

                return(Visit(pie));
            }



            var methodName    = m.Method.Name;
            var declaringType = m.Method.DeclaringType;

            if (declaringType == typeof(System.Convert))
            {
                Expression operand = null;
                Type       toType  = null;
                if (m.Method.Name.StartsWith("To"))
                {
                    toType  = ClassLoader.Load("System." + m.Method.Name.Replace("To", ""));
                    operand = m.Arguments[0];
                }

                if (operand != null && toType != null && toType != Types.Object)
                {
                    return(Expression.Call(MethodRepository.GetConvertMethod(operand.Type, toType), operand));
                }
            }

            if (typeof(TypeConverter).IsAssignableFrom(declaringType))
            {
                Expression operand = null;
                Type       toType  = null;

                if (methodName.StartsWith("ConvertFrom"))
                {
                    var  c             = m.Object as ConstantExpression;
                    Type converterType = null;
                    if (c != null)
                    {
                        converterType = (m.Object as ConstantExpression).Value.GetType();
                    }
                    else
                    {
                        var ma = m.Object as MemberExpression;
                        if (ma != null)
                        {
                            c = ma.Expression as ConstantExpression;
                            if (c == null)
                            {
                                throw new NotSupportedException(string.Format("The method '{0}' is not supported", m.Method.Name));
                            }

                            converterType = ma.Member.GetGetter()(c.Value).GetType();
                        }
                    }
                    toType = ClassLoader.Load("System." + converterType.Name.Replace("Converter", ""));
                    if (toType == null)
                    {
                        throw new NotSupportedException(string.Format("The method '{0}' is not supported", m.Method.Name));
                    }

                    if (methodName == "ConvertFrom" && m.Arguments.Count == 1)
                    {
                        operand = m.Arguments[0];
                    }
                    else if (methodName == "ConvertFromString" && m.Arguments.Count == 1)
                    {
                        operand = m.Arguments[0];
                    }
                    else if (methodName == "ConvertFromInvariantString" && m.Arguments.Count == 1)
                    {
                        operand = m.Arguments[0];
                    }
                }
                else if (methodName == "ConvertTo" && m.Arguments.Count == 2)
                {
                    operand = m.Arguments[0];
                    toType  = (m.Arguments[1] as ConstantExpression).Value as Type;
                }
                else if (methodName == "ConvertToInvariantString" && m.Arguments.Count == 1)
                {
                    operand = m.Arguments[0];
                    toType  = Types.String;
                }
                else if (methodName == "ConvertToString" && m.Arguments.Count == 1)
                {
                    operand = m.Arguments[0];
                    toType  = Types.String;
                }

                if (operand != null && toType != null && toType != Types.Object)
                {
                    return(Expression.Call(MethodRepository.GetConvertMethod(operand.Type, toType), operand));
                }
                throw new NotSupportedException(string.Format("The method '{0}' is not supported", methodName));
            }

            if (methodName == "Parse" &&
                m.Method.IsStatic &&
                (declaringType.IsValueType || declaringType.IsNullable()) &&
                m.Arguments.Count == 1 &&
                m.Method.ReturnType == m.Type)
            {
                Expression operand = m.Arguments[0];
                Type       toType  = declaringType.IsNullable() ? Nullable.GetUnderlyingType(declaringType) : declaringType;
                return(Expression.Call(MethodRepository.GetConvertMethod(operand.Type, toType), operand));
            }
            if (declaringType == Types.String)
            {
                if (methodName == "Concat")
                {
                    return(BindConcat(m.Arguments.ToArray()));
                }
                if (methodName == "Join")
                {
                    return(BindJoin(m));
                }
            }

            if (methodName == "ContainsValue" && IsSameOrParent(typeof(IDictionary <,>), declaringType))
            {
                var args = GetGenericArguments(declaringType, typeof(IDictionary <,>));
                var minf = EnumerableMethods
                           .First(s => s.Name == "Contains" && s.GetParameters().Length == 2)
                           .MakeGenericMethod(args[1]);

                return(Expression.Call(
                           minf,
                           Expression.PropertyOrField(m.Object, "Values"),
                           m.Arguments[0]));
            }
            if (methodName == "ContainsKey" && IsSameOrParent(typeof(IDictionary <,>), declaringType))
            {
                var args = GetGenericArguments(declaringType, typeof(IDictionary <,>));
                var minf = EnumerableMethods
                           .First(s => s.Name == "Contains" && s.GetParameters().Length == 2)
                           .MakeGenericMethod(args[1]);

                return(Expression.Call(
                           minf,
                           Expression.PropertyOrField(m.Object, "Keys"),
                           m.Arguments[0]));
            }


            if (declaringType.FullName == DLinq.StrSqlMethhodsType && declaringType.Assembly.GetName().Name == DLinq.StrAssemblyName)
            {
                DLinq.Init(declaringType.Assembly);
                return(Visit(m));
            }
            //if (methodName == "Like" && declaringType == typeof(SqlFunctions) && m.Arguments.Count == 5)
            //{
            //    return BindLike(
            //        m.Arguments[0]
            //        , m.Arguments[1]
            //        , (bool)(m.Arguments[2] as ConstantExpression).Value
            //        , (bool)(m.Arguments[3] as ConstantExpression).Value
            //        , (bool)(m.Arguments[4] as ConstantExpression).Value);
            //}

            if (typeof(Queryable).IsAssignableFrom(declaringType) || typeof(Enumerable).IsAssignableFrom(declaringType))
            {
                var elementType = NLite.Data.Linq.Internal.ReflectionHelper.GetElementType(m.Arguments[0].Type);
                switch (methodName)
                {
                case "Contains":
                    EntityMapping mapping;
                    if (DbContext.dbConfiguration.mappings.TryGetValue(elementType.TypeHandle.Value, out mapping))
                    {
                        // Expression left =
                    }
                    break;
                    //case "Aggregate":
                    //    {
                    //        var type = NLite.Reflection.TypeHelper.GetElementType(m.Arguments[0].Type);
                    //        if (type.IsNullable())
                    //            type = Nullable.GetUnderlyingType(type);
                    //        if (type.IsClass && type != Types.String)
                    //            throw new NotSupportedException("Not support 'Aggregate' function for complex type.");
                    //        break;
                    //    }
                    //case "ElementAt":
                    //    var index = m.Arguments[1];
                    //    var elementType = NLite.Reflection.TypeHelper.GetElementType(m.Arguments[0].Type);
                    //    var c = index as ConstantExpression;
                    //    if (c != null)
                    //    {
                    //        if((int)c.Value == 0)
                    //            return Expression.Call(typeof(Enumerable), "Take", new Type[] { elementType }, m.Arguments[0], Expression.Constant(1, Types.Int32));
                    //        index = Expression.Constant((int)c.Value + 1, Types.Int32);
                    //    }
                    //    else
                    //        index = Expression.Add(index, Expression.Constant(1, Types.Int32));
                    //    var s = Expression.Call(typeof(Enumerable), "Skip", new Type[] { elementType },m.Arguments[0], index);
                    //    return Expression.Call(typeof(Enumerable), "Take", new Type[] { elementType },s, Expression.Constant(1,Types.Int32));
                }
            }

            if (IsSameOrParent(typeof(IEnumerable <>), declaringType) &&
                !declaringType.IsArray &&
                m.Object != null &&
                m.Object.NodeType == ExpressionType.Constant &&
                !typeof(IQueryable).IsAssignableFrom(declaringType))
            {
                switch (methodName)
                {
                case "Contains":
                    var elementType = NLite.Data.Linq.Internal.ReflectionHelper.GetElementType(declaringType);
                    if (!DbContext.dbConfiguration.HasClass(elementType) && elementType != Types.Char)
                    {
                        var lst = (m.Object as ConstantExpression).Value as IEnumerable;
                        if (lst != null)
                        {
                            var items = lst.Cast <object>().ToArray();
                            var arry  = Array.CreateInstance(elementType, items.Length);
                            for (int i = 0; i < items.Length; i++)
                            {
                                arry.SetValue(items[i], i);
                            }
                            Expression array = Expression.Constant(arry);

                            var containsMethod = EnumerableMethods
                                                 .First(s => s.Name == "Contains" && s.GetParameters().Length == 2)
                                                 .MakeGenericMethod(elementType);
                            m = Expression.Call(containsMethod, array, m.Arguments[0]);
                        }
                    }
                    break;
                }
            }
            return(m);
        }
示例#22
0
 private bool IsValidNativeMethod(MethodCallExpression express, string methodName)
 {
     return(MethodMapping.ContainsKey(methodName) && express.Method.DeclaringType.Namespace == ("System"));
 }
示例#23
0
        /// <summary>
        /// Map methods to actions.
        /// </summary>
        /// <param name="info">Method to inspect.</param>
        /// <remarks>Goes through all custom action attributes to check which HTTP methods
        /// the action is valid for.</remarks>
        /// <exception cref="ActionMappingException">Mapping collision. Do not both suffix methods with a verb and use ValidFor attribute.</exception>
        private void MapMethod(MethodInfo info)
        {
            string verb;
            string methodName = info.Name;
            bool isFound = TryGetVerb(ref methodName, out verb);

            MethodMapping mapping;
            if (!_methods.TryGetValue(methodName.ToLower(), out mapping))
            {
                mapping = new MethodMapping();
                _methods.Add(methodName.ToLower(), mapping);
            }

            // specified a verb
            if (isFound)
            {
                _logger.Trace("Mapped " + _uri + "." + methodName.ToLower() + " to " + verb);
                mapping.IsMethodsSpecified = true;
                mapping.Add(verb, info);
            }


            // Check if method is valid only for a few verbs
            foreach (object customAttribute in info.GetCustomAttributes(false))
            {
                var attr = customAttribute as ValidForAttribute;
                if (attr == null) continue;
                if (isFound)
                    throw new ActionMappingException(
                        "Mapping collision. Do not both suffix methods with a verb and use ValidFor attribute.");

                mapping.IsMethodsSpecified = true;
                
            }

            if (!mapping.IsMethodsSpecified)
            {
                _logger.Trace("Mapped " + _uri + "." + methodName.ToLower() + " to ALL verbs");
                mapping.Add(verb, info);
            }
        }
示例#24
0
            public static void Init(Assembly asm)
            {
                var instance = new ULinq();

                //var asm = linqToSqlClassType.Assembly;
                EntityRefType = asm.GetType(StrEntityRefType);
                EntitySetType = asm.GetType(StrEntitySetType);
                BinaryType    = asm.GetType(StrBinaryType);
                BinaryCtor    = BinaryType.GetConstructor(new Type[] { typeof(byte[]) }).GetCreator();
                SqlType.TypeMap[BinaryType.TypeHandle.Value.GetHashCode()] = DBType.Binary;

                instance.Table      = new TableAttribute();
                instance.Table.Type = asm.GetType(ULinq.StrTableAttributeType);
                instance.Table.Name = instance.Table.Type.GetProperty("Name").GetGetter();

                instance.Column                 = new ColumnAttribute();
                instance.Column.Type            = asm.GetType(ULinq.StrColumnAttributeType);
                instance.Column.Name            = instance.Column.Type.GetProperty("Name").GetGetter();
                instance.Column.CanBeNull       = instance.Column.Type.GetProperty("CanBeNull").GetGetter();
                instance.Column.IsDbGenerated   = instance.Column.Type.GetProperty("IsDbGenerated").GetGetter();
                instance.Column.IsPrimaryKey    = instance.Column.Type.GetProperty("IsPrimaryKey").GetGetter();
                instance.Column.IsVersion       = instance.Column.Type.GetProperty("IsVersion").GetGetter();
                instance.Column.AutoSync        = instance.Column.Type.GetProperty("AutoSync").GetGetter();
                instance.Column.DbType          = instance.Column.Type.GetProperty("DbType").GetGetter();
                instance.Column.Expression      = instance.Column.Type.GetProperty("Expression").GetGetter();
                instance.Column.IsDiscriminator = instance.Column.Type.GetProperty("IsDiscriminator").GetGetter();

                instance.Column.Storage     = instance.Column.Type.GetProperty("Storage").GetGetter();
                instance.Column.UpdateCheck = instance.Column.Type.GetProperty("UpdateCheck").GetGetter();

                instance.Association              = new AssociationAttribute();
                instance.Association.Type         = asm.GetType(ULinq.StrAssociationAttributeType);
                instance.Association.ThisKey      = instance.Association.Type.GetProperty("ThisKey").GetGetter();
                instance.Association.OtherKey     = instance.Association.Type.GetProperty("OtherKey").GetGetter();
                instance.Association.IsForeignKey = instance.Association.Type.GetProperty("IsForeignKey").GetGetter();

                var sqlMethodsType = asm.GetType(ULinq.StrSqlMethhodsType);
                //var flags = BindingFlags.Public | BindingFlags.Static;
                var dateDiffDay = sqlMethodsType.GetMethod("DateDiffDay", new Type[] { typeof(DateTime), typeof(DateTime) });

                MethodMapping.Mappings[dateDiffDay] = MethodMapping.Lambda <DateTime, DateTime, int>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Day, startTime, endTime));

                var dateDiffHour = sqlMethodsType.GetMethod("DateDiffHour", new Type[] { typeof(DateTime), typeof(DateTime) });

                MethodMapping.Mappings[dateDiffHour] = MethodMapping.Lambda <DateTime, DateTime, int>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Hour, startTime, endTime));

                var dateDiffMicrosecond = sqlMethodsType.GetMethod("DateDiffMicrosecond", new Type[] { typeof(DateTime), typeof(DateTime) });

                MethodMapping.Mappings[dateDiffMicrosecond] = MethodMapping.Lambda <DateTime, DateTime, int>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Microsecond, startTime, endTime));

                var dateDiffMillisecond = sqlMethodsType.GetMethod("DateDiffMillisecond", new Type[] { typeof(DateTime), typeof(DateTime) });

                MethodMapping.Mappings[dateDiffMillisecond] = MethodMapping.Lambda <DateTime, DateTime, int>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Millisecond, startTime, endTime));

                var dateDiffMinute = sqlMethodsType.GetMethod("DateDiffMinute", new Type[] { typeof(DateTime), typeof(DateTime) });

                MethodMapping.Mappings[dateDiffMinute] = MethodMapping.Lambda <DateTime, DateTime, int>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Minute, startTime, endTime));

                var dateDiffMonth = sqlMethodsType.GetMethod("DateDiffMonth", new Type[] { typeof(DateTime), typeof(DateTime) });

                MethodMapping.Mappings[dateDiffMonth] = MethodMapping.Lambda <DateTime, DateTime, int>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Month, startTime, endTime));

                var dateDiffNanosecond = sqlMethodsType.GetMethod("DateDiffNanosecond", new Type[] { typeof(DateTime), typeof(DateTime) });

                MethodMapping.Mappings[dateDiffNanosecond] = MethodMapping.Lambda <DateTime, DateTime, int>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Nanosecond, startTime, endTime));

                var dateDiffSecond = sqlMethodsType.GetMethod("DateDiffSecond", new Type[] { typeof(DateTime), typeof(DateTime) });

                MethodMapping.Mappings[dateDiffSecond] = MethodMapping.Lambda <DateTime, DateTime, int>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Second, startTime, endTime));

                var dateDiffYear = sqlMethodsType.GetMethod("DateDiffYear", new Type[] { typeof(DateTime), typeof(DateTime) });

                MethodMapping.Mappings[dateDiffYear] = MethodMapping.Lambda <DateTime, DateTime, int>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Year, startTime, endTime));

                //
                var dateDiffDayForNullable = sqlMethodsType.GetMethod("DateDiffDay", new Type[] { typeof(DateTime?), typeof(DateTime?) });

                MethodMapping.Mappings[dateDiffDayForNullable] = MethodMapping.Lambda <DateTime?, DateTime?, int?>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Day, startTime, endTime));

                var dateDiffHourForNullable = sqlMethodsType.GetMethod("DateDiffHour", new Type[] { typeof(DateTime?), typeof(DateTime?) });

                MethodMapping.Mappings[dateDiffHourForNullable] = MethodMapping.Lambda <DateTime?, DateTime?, int?>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Hour, startTime, endTime));

                var dateDiffMicrosecondForNullable = sqlMethodsType.GetMethod("DateDiffMicrosecond", new Type[] { typeof(DateTime?), typeof(DateTime?) });

                MethodMapping.Mappings[dateDiffMicrosecondForNullable] = MethodMapping.Lambda <DateTime?, DateTime?, int?>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Microsecond, startTime, endTime));

                var dateDiffMillisecondForNullable = sqlMethodsType.GetMethod("DateDiffMillisecond", new Type[] { typeof(DateTime?), typeof(DateTime?) });

                MethodMapping.Mappings[dateDiffMillisecondForNullable] = MethodMapping.Lambda <DateTime?, DateTime?, int?>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Millisecond, startTime, endTime));

                var dateDiffMinuteForNullable = sqlMethodsType.GetMethod("DateDiffMinute", new Type[] { typeof(DateTime?), typeof(DateTime?) });

                MethodMapping.Mappings[dateDiffMinuteForNullable] = MethodMapping.Lambda <DateTime?, DateTime?, int?>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Minute, startTime, endTime));

                var dateDiffMonthForNullable = sqlMethodsType.GetMethod("DateDiffMonth", new Type[] { typeof(DateTime?), typeof(DateTime?) });

                MethodMapping.Mappings[dateDiffMonthForNullable] = MethodMapping.Lambda <DateTime?, DateTime?, int?>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Month, startTime, endTime));

                var dateDiffNanosecondForNullable = sqlMethodsType.GetMethod("DateDiffNanosecond", new Type[] { typeof(DateTime?), typeof(DateTime?) });

                MethodMapping.Mappings[dateDiffNanosecondForNullable] = MethodMapping.Lambda <DateTime?, DateTime?, int?>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Nanosecond, startTime, endTime));

                var dateDiffSecondForNullable = sqlMethodsType.GetMethod("DateDiffSecond", new Type[] { typeof(DateTime?), typeof(DateTime?) });

                MethodMapping.Mappings[dateDiffSecondForNullable] = MethodMapping.Lambda <DateTime?, DateTime?, int?>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Second, startTime, endTime));

                var dateDiffYearForNullable = sqlMethodsType.GetMethod("DateDiffYear", new Type[] { typeof(DateTime?), typeof(DateTime?) });

                MethodMapping.Mappings[dateDiffYearForNullable] = MethodMapping.Lambda <DateTime?, DateTime?, int?>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Year, startTime, endTime));

                Instance = instance;
            }