示例#1
0
        private DbCommand GetCommandWithParameters(HttpContext context,
                                                   DbConnection con,
                                                   Entity ent,
                                                   Method method, Dictionary <string, object> parameterOfUser)
        {
            if (con == null)
            {
                throw new ArgumentNullException(nameof(con));
            }
            if (ent == null)
            {
                throw new ArgumentNullException(nameof(ent));
            }
            if (method == null)
            {
                throw new ArgumentNullException(nameof(method));
            }
            if (parameterOfUser == null)
            {
                parameterOfUser = new Dictionary <string, object>();
            }
            var cmd        = con.AssureOpen().CreateSPCommand(method.SP);
            var parameters = parameterProvider.GetApiParameters(ent, method.SP);

            SPParameter[] sPParameters = null;
            foreach (var apiPrm in parameters)
            {
                var prm = apiPrm.WebApiName == null ? null
                        :
                          ent.ContainsPathParameter(apiPrm.WebApiName) ?
                          context.GetRouteValue(apiPrm.WebApiName) :
                          parameterOfUser.FirstOrDefault(p => p.Key.Equals(apiPrm.WebApiName,
                                                                           StringComparison.CurrentCultureIgnoreCase)).Value;

                object value = apiPrm.GetValue(context, prm);
                if (value is System.Data.DataTable dt)
                {
                    var cmdPrm = cmd.CreateParameter();
                    cmdPrm.ParameterName = "@" + apiPrm.SqlName;
                    cmdPrm.Value         = value;
                    if (cmdPrm.GetType().FullName == "System.Data.SqlClient.SqlParameter" ||
                        cmdPrm.GetType().FullName == "Microsoft.Data.SqlClient.SqlParameter")
                    {
                        // Reflection set SqlDbType in order to avoid
                        // referecnting the deprecated SqlClient Nuget Package or the too new Microsoft SqlClient package

                        // see https://devblogs.microsoft.com/dotnet/introducing-the-new-microsoftdatasqlclient/

                        // cmdPrm.SqlDbType = System.Data.SqlDbType.Structured;
                        cmdPrm.GetType().GetProperty("SqlDbType", System.Reflection.BindingFlags.Public |
                                                     System.Reflection.BindingFlags.Instance |
                                                     System.Reflection.BindingFlags.SetProperty)
                        .SetValue(cmdPrm, System.Data.SqlDbType.Structured);
                    }
                    cmd.Parameters.Add(cmdPrm);
                }
                else if (value as string == "")
                {
                    sPParameters = sPParameters ?? sPParametersProvider.GetSPParameters(method.SP, con);
                    var spPrm = sPParameters.First(f => f.SqlName == apiPrm.SqlName);
                    if (spPrm.DbType.NetType == typeof(System.DateTime) ||
                        spPrm.DbType.JsType == "number" ||
                        spPrm.DbType.JsType == "integer")
                    {
                        cmd.AddCommandParameter(apiPrm.SqlName, DBNull.Value);
                    }
                }
                else
                {
                    cmd.AddCommandParameter(apiPrm.SqlName, value ?? System.DBNull.Value);
                }
            }
            return(cmd);
        }
        /// <summary>
        /// Gets the command with parameters
        /// </summary>
        /// <param name="context">The http context or null if not in an http context</param>
        /// <param name="getRouteValue">If context is null, you need to provider route parameters with this Func</param>
        /// <param name="con">The db connection</param>
        /// <param name="ent">The entity</param>
        /// <param name="method">The method</param>
        /// <param name="parameterOfUser">The parameters as provided from user</param>
        /// <returns>Returns a DbCommand Object, NOT executed</returns>
        public virtual async Task <DbCommand> GetCommandWithParameters(HttpContext?context,
                                                                       Func <string, object>?getRouteValue,
                                                                       DbConnection con,
                                                                       Entity ent,
                                                                       Method method,
                                                                       Dictionary <string, object> parameterOfUser)
        {
            if (con == null)
            {
                throw new ArgumentNullException(nameof(con));
            }
            if (ent == null)
            {
                throw new ArgumentNullException(nameof(ent));
            }
            if (method == null)
            {
                throw new ArgumentNullException(nameof(method));
            }
            if (parameterOfUser == null)
            {
                parameterOfUser = new Dictionary <string, object>(StringComparer.CurrentCultureIgnoreCase);
            }
            if (getRouteValue == null)
            {
                if (context == null)
                {
                    throw new ArgumentNullException(nameof(getRouteValue));
                }
                getRouteValue = (s) => context.GetRouteValue(s);
            }
            var cmd = con.AssureOpen().CreateSPCommand(method.SP);

            if (method.CommandTimeout != null)
            {
                cmd.CommandTimeout = method.CommandTimeout.Value;
            }
            var(inputParameters, outputParameters) = await parameterProvider.GetApiParameters(new Filter.ParameterInterceptorContext(ent, method, false), method.IgnoreParameters, con);

            IReadOnlyCollection <SPParameter>?sPParameters = null;

            foreach (var apiPrm in inputParameters)
            {
                var prm = apiPrm.WebApiName == null ? parameterOfUser /* make it possible to use some logic */
                        :
                          ent.ContainsPathParameter(apiPrm.WebApiName) ?
                          getRouteValue(apiPrm.WebApiName) :
                          parameterOfUser.FirstOrDefault(p => p.Key.Equals(apiPrm.WebApiName,
                                                                           StringComparison.CurrentCultureIgnoreCase)).Value;
                if (apiPrm.SqlName == null)
                {
                    continue;
                }
                bool hasValue = !apiPrm.RequiresUserProvidedValue ||
                                (apiPrm.WebApiName != null && ent.ContainsPathParameter(apiPrm.WebApiName)) ||
                                parameterOfUser.Any(p => p.Key.Equals(apiPrm.WebApiName,
                                                                      StringComparison.CurrentCultureIgnoreCase));

                if (hasValue)
                {
                    var value = apiPrm.GetValue(context, prm);
                    ParameterDirection parameterDirection =
                        outputParameters.Any(p => p.SqlName.Equals(apiPrm.SqlName, StringComparison.CurrentCultureIgnoreCase)) ? ParameterDirection.InputOutput
                            : ParameterDirection.Input;
                    if (value is System.Data.DataTable dt)
                    {
                        var cmdPrm = cmd.CreateParameter();
                        cmdPrm.ParameterName = "@" + apiPrm.SqlName;
                        cmdPrm.Value         = value;
                        cmdPrm.Direction     = parameterDirection;
                        if (cmdPrm.GetType().FullName == "System.Data.SqlClient.SqlParameter" ||
                            cmdPrm.GetType().FullName == "Microsoft.Data.SqlClient.SqlParameter")
                        {
                            // Reflection set SqlDbType in order to avoid
                            // referecnting the deprecated SqlClient Nuget Package or the too new Microsoft SqlClient package

                            // see https://devblogs.microsoft.com/dotnet/introducing-the-new-microsoftdatasqlclient/

                            // cmdPrm.SqlDbType = System.Data.SqlDbType.Structured;
                            cmdPrm.GetType().GetProperty("SqlDbType", System.Reflection.BindingFlags.Public |
                                                         System.Reflection.BindingFlags.Instance |
                                                         System.Reflection.BindingFlags.SetProperty) !
                            .SetValue(cmdPrm, System.Data.SqlDbType.Structured);
                        }
                        cmd.Parameters.Add(cmdPrm);
                    }
                    else if (value as string == "")
                    {
                        sPParameters = sPParameters ?? await sPParametersProvider.GetSPParameters(method.SP, con);

                        var spPrm = sPParameters.First(f => f.SqlName == apiPrm.SqlName);
                        if (spPrm.DbType.NetType == typeof(System.DateTime) ||
                            spPrm.DbType.NetType == typeof(System.DateTimeOffset) ||
                            spPrm.DbType.JsType == "number" ||
                            spPrm.DbType.JsType == "integer" ||
                            spPrm.DbType.JsType == "boolean")
                        {
                            cmd.AddCommandParameter(apiPrm.SqlName, DBNull.Value, configure: c =>
                            {
                                c.Direction = parameterDirection;
                            });
                        }
                        else
                        {
                            cmd.AddCommandParameter(apiPrm.SqlName, value, configure: c =>
                            {
                                c.Direction = parameterDirection;
                            });
                        }
                    }
                    else if (value == null)
                    {
                        sPParameters = sPParameters ?? await sPParametersProvider.GetSPParameters(method.SP, con);

                        var spPrm = sPParameters.First(f => f.SqlName == apiPrm.SqlName);
                        cmd.AddCommandParameter(apiPrm.SqlName, DBNull.Value, spPrm.DbType.NetType, configure: c =>
                        {
                            c.Direction = parameterDirection;
                        });
                    }
                    else
                    {
                        cmd.AddCommandParameter(apiPrm.SqlName, value ?? System.DBNull.Value, configure: c =>
                        {
                            c.Direction = parameterDirection;
                        });;
                    }
                }
            }
            foreach (var op in outputParameters)
            {
                bool isAlreadyInput = inputParameters.Any(i => i.SqlName != null && i.SqlName.Equals(op.SqlName, StringComparison.CurrentCultureIgnoreCase));
                if (!isAlreadyInput)
                {
                    cmd.AddCommandParameter(op.SqlName, DBNull.Value, op.DbType.NetType, configure: c =>
                    {
                        c.Direction = ParameterDirection.Output;
                    });
                }
            }
            return(cmd);
        }