Ejemplo n.º 1
0
        /// <summary>
        /// Executes the storedProcedure against the connString and returns a IEnumerable<TEntity>
        /// It will also load the partialParam with the current row's non-TEntity values.
        ///
        /// If you need the return value, access it dynamically from partialParam
        /// Note: @RETURN_VALUE is returned as ReturnValue
        ///
        /// NOTE: Shouldn't forget to initialize the partialParam as an ExpandoObject
        /// </summary>
        /// <typeparam name="TEntity">The [TableName]VD associated with the table entity coming from the stored procedure.</typeparam>
        /// <param name="connString">The connection string that identifies the database server</param>
        /// <param name="storedProcedure">The stored procedure to execute</param>
        /// <param name="partialParam">Populated with row/record values that ExecuteReader can't find a corresponding property in your TEntity</param>
        /// <param name="entity">An entity that contain values which should be used as parameters for storedProcedure</param>
        /// <param name="includeReturnValue">Specify if the Return Value from the storedProcedure should be included</param>
        /// <param name="implicitCast">Support of implicit or explict cast</param>
        /// <returns></returns>
        public static TEntity ExecuteReaderSingle <TEntity>(IDbConnection connection, string storedProcedure, dynamic partialParam, TEntity entity = null, bool includeReturnValue = true, bool implicitCast = true) where TEntity : class, new()
        {
            //db value don't exist in entity
            if (partialParam == null)
            {
                partialParam = new ExpandoObject();
            }
            if (entity == null)
            {
                entity = new TEntity();
            }

            //if (partialParam == null) throw new Exception("Initialize the 'partialParam' parameter to an ExpandoObject!");
            if (partialParam.GetType() != typeof(ExpandoObject))
            {
                throw new Exception("Initialize the 'partialParam' parameter to an ExpandoObject!");
            }

            var param = partialParam as IDictionary <string, object>;

            //NOTE: partialParam take presedence over the entity properties. Basically to give you control
            //NOTE: Output Parameters will return no value. Use ExecuteNonQuery or ExecuteScalar instead
            Type            entityType = typeof(TEntity);
            IList <TEntity> entites    = new List <TEntity>();

            using (connection) {
                using (IDbCommand command = connection.CreateCommand()) {
                    command.CommandText = storedProcedure;
                    command.CommandType = CommandType.StoredProcedure;

                    if (connection.State != ConnectionState.Open)
                    {
                        connection.Open();                                          //new List<IDataParameter>(); //
                    }
                    List <IDataParameter> paramList = (List <IDataParameter>)SqlHelperParameterCache.GetSpParameterSet(connection, storedProcedure, includeReturnValue);


                    /*
                     * For now, use the foreach
                     * string _key = storedProcedure + entityType.Name + paramList.GetHashCode().ToString();
                     * AttachParamToCommand _genMethod;
                     * TryGetQueryCache(_key, out _genMethod);
                     * if (_genMethod == null) {
                     *  _genMethod = GenerateAttachParamToCommand<TEntity>(command, paramList, ref partialParam);
                     *  SetQueryCache(_key, _genMethod);
                     * }
                     * _genMethod(command, paramList, entity, ref partialParam);*/


                    //Initialize || Set param values
                    foreach (IDataParameter p in paramList)
                    {
                        if (p.Direction != ParameterDirection.ReturnValue)
                        {
                            bool   hasSetParamValue = false;
                            string paramName        = p.ParameterName.TrimStart('@');

                            if (HasPartialProperty(partialParam, paramName))
                            {
                                p.Value = param[paramName]; hasSetParamValue = true;
                            }
                            else
                            {
                                //Find the parameter in the entity
                                PropertyInfo prop = typeof(TEntity).GetProperty(paramName);

                                if (prop != null)
                                {
                                    p.Value = prop.GetValue(entity, null) ?? DBNull.Value; hasSetParamValue = true;
                                }
                            }

                            if (!hasSetParamValue && p.Direction == ParameterDirection.Input)
                            {
                                throw new ArgumentException("The required stored procedure parameter (" + paramName + ") does not exist in entity or was not specified!", paramName);
                            }
                        }

                        command.Parameters.Add(p);
                    }


                    using (IDataReader dr = command.ExecuteReader()) {
                        if (typeof(TEntity).IsClass)
                        {
                            int                rowIndex = 0;
                            string             _drClassDeserializerKey = storedProcedure + entityType.Name;
                            EntityDeserializer _drClassDeserializer;
                            TryGetQueryCache(_drClassDeserializerKey, out _drClassDeserializer);
                            if (_drClassDeserializer == null)
                            {
                                _drClassDeserializer = DeserializeEntity <TEntity>(dr,
                                                                                   ++rowIndex, command.Parameters, entites, entityType, partialParam, implicitCast);

                                SetQueryCache(_drClassDeserializerKey, _drClassDeserializer);
                            }

                            //TODO: Get table columns and cache it
                            if (dr.Read())   //true => implicitCast
                            {
                                return((TEntity)_drClassDeserializer(dr, true, partialParam) ?? new TEntity());
                            }
                        }
                        else
                        {
                            throw new Exception("Non-Class entity types are not supported for ExecuteReader");
                        }
                    }
                }
            }

            return(new TEntity());
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Executes the query, and returns the first column of the first row in the
        /// resultset returned by the query. Extra columns or rows are ignored.
        /// It will also load the partialParam with the current row's non-TEntity values.
        ///
        /// If you need the return value, access it dynamically from partialParam
        /// Note: @RETURN_VALUE is returned as ReturnValue
        /// </summary>
        /// <typeparam name="TEntity">The [TableName]VD associated with the table entity coming from the stored procedure.</typeparam>
        /// <typeparam name="TReturnValue">The type for the firs column of the first row in the resultset</typeparam>
        /// <param name="connString">The connection string that identifies the database server</param>
        /// <param name="storedProcedure">The stored procedure to execute</param>
        /// <param name="partialParam">Populated with row/record values that ExecuteReader can't find a corresponding property in your TEntity</param>
        /// <param name="entity">Populated with row/record values that ExecuteReader can't find a corresponding property in your TEntity</param>
        /// <returns>The first column of the first row in the resultset</returns>
        public static TReturnValue ExecuteScalar <TEntity, TReturnValue>(IDbConnection connection, string storedProcedure, ref dynamic partialParam, TEntity entity = null) where TEntity : class, new()
        {
            TReturnValue returnValue;

            //db value don't exist in entity
            if (entity == null)
            {
                entity = new TEntity();
            }
            if (partialParam == null)
            {
                partialParam = new ExpandoObject();
            }
            if (partialParam.GetType() != typeof(ExpandoObject))
            {
                throw new Exception("Initialize the 'partialParam' parameter to an ExpandoObject!");
            }

            var param = partialParam as IDictionary <string, object>;

            //TODO: partialParam take presedence over the entity properties. Basically to give you control
            //TODO: Output Parameters will return no value. Use ExecuteNonQuery or ExecuteScalar instead

            IList <TEntity> list = new List <TEntity>();

            using (connection) {
                using (IDbCommand command = connection.CreateCommand()) {
                    command.CommandText = storedProcedure;
                    command.CommandType = CommandType.StoredProcedure;

                    if (connection.State != ConnectionState.Open)
                    {
                        connection.Open();
                    }

                    IList <IDataParameter> paramList = SqlHelperParameterCache.GetSpParameterSet(connection, storedProcedure, true);

                    //Initialize || Set param values
                    foreach (IDataParameter p in paramList)
                    {
                        if (p.Direction != ParameterDirection.ReturnValue)
                        {
                            bool   hasSetParamValue = false;
                            string paramName        = p.ParameterName.TrimStart('@');

                            //Check in the partial pram
                            //param = partialParam.Get(paramName);

                            if (HasPartialProperty(partialParam, paramName))
                            {
                                p.Value = param[paramName]; hasSetParamValue = true;
                            }
                            else
                            {
                                //Find the parameter in the entity
                                PropertyInfo prop = typeof(TEntity).GetProperty(paramName);

                                if (prop != null)
                                {
                                    p.Value = prop.GetValue(entity, null) ?? DBNull.Value; hasSetParamValue = true;
                                }
                            }

                            if (!hasSetParamValue && p.Direction == ParameterDirection.Input)
                            {
                                throw new ArgumentException("The required stored procedure parameter (" + paramName + ") does not exist in entity or was not specified!", paramName);
                            }
                        }

                        command.Parameters.Add(p);
                    }

                    var o = command.ExecuteScalar();
                    returnValue = (o == null) ? default(TReturnValue) : (TReturnValue)o;

                    foreach (SqlParameter p in command.Parameters)
                    {
                        string _paramName = p.ParameterName.TrimStart('@');
                        if (_paramName == "RETURN_VALUE")
                        {
                            param["ReturnValue"] = p.Value;
                        }
                        else
                        {
                            param[p.ParameterName.TrimStart('@')] = p.Value;
                        }
                    }

                    command.Parameters.Clear();
                }
            }

            return(returnValue);
        }