Ejemplo n.º 1
0
        /// <summary>
        /// 通过参数化SQL、匿名对象的方式,创建CPQuery对象实例
        /// </summary>
        /// <example>
        /// <para>下面的代码演示了通过参数化SQL,匿名对象的方式,创建CPQuery对象实例的用法</para>
        /// <code>
        /// //声明匿名类型
        /// var product = new {
        ///		ProductName = "产品名称",
        ///		Quantity = 10
        /// };
        ///
        /// //SQL中的参数名就是@加匿名类型的属性名
        /// CPQuery.From("INSERT INTO Products(ProductName, Quantity) VALUES(@ProductName, @Quantity)", product).ExecuteNonQuery();
        /// </code>
        /// </example>
        /// <param name="parameterizedSQL">参数化的SQL字符串</param>
        /// <param name="argsObject">匿名对象</param>
        /// <returns>CPQuery对象实例</returns>
        public static CPQuery From(string parameterizedSQL, object argsObject)
        {
            if (string.IsNullOrEmpty(parameterizedSQL))
            {
                throw new ArgumentNullException("parameterizedSQL");
            }


            CPQuery query = new CPQuery(parameterizedSQL);

            if (argsObject != null)
            {
                PropertyInfo[] properties = argsObject.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);
                foreach (PropertyInfo pInfo in properties)
                {
                    object value = pInfo.FastGetValue(argsObject);
                    string name  = "@" + pInfo.Name;

                    if (value == null || value == DBNull.Value)
                    {
                        query._command.Parameters.AddWithValue(name, DBNull.Value);
                        //SqlParameter paramter = new SqlParameter(name, DBNull.Value);
                        //paramter.SqlDbType = SqlDbType.Variant;
                        //query._command.Parameters.Add(paramter);
                        //throw new ArgumentException("输入参数的属性值不能为空。");
                    }
                    else
                    {
                        SqlParameter parameter = value as SqlParameter;
                        if (parameter != null)
                        {
                            query._command.Parameters.Add(parameter);
                        }
                        else
                        {
                            query._command.Parameters.AddWithValue(name, value);
                        }
                    }
                }
            }

            return(query);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// 更新数据实体对应的记录。
        /// </summary>
        /// <example>
        /// <para>下面的代码演示了Update()方法的用法</para>
        /// <code>
        /// //Contract类需要继承自BaseEntity,并且需要放在以*.Entity.dll结尾的程序集中
        /// Contract contract = new Contract();
        ///
        /// //为类的主键赋值
        /// contract.ContractGUID = Reuqest.QueryString["ContractGUID"];
        ///
        /// //为类的其他字段赋值
        /// //contract.ContractName = Request.Form["ContractName"];
        /// //...
        ///
        /// int count = contract.Update();
        /// //更新成功后,count等于1
        /// </code>
        /// </example>
        /// <exception cref="InvalidProgramException">如果数据实体类型的定义不符合规范,就会抛出此异常</exception>
        /// <exception cref="InvalidOperationException">类没有定义主键,即没有任何一个属性被标记为PrimaryKey=true,则抛出此异常</exception>
        /// <returns>返回ADO.NET的原始结果</returns>
        public virtual int Update()
        {
            CPQuery query = GetCPQuery(7, new object[] { this, bakObject });

            if (query == null)
            {
                return(0);
            }

            if (_funcBefore != null)
            {
                if (_funcBefore(query) == false)
                {
                    return(-1);
                }
            }

            return(query.ExecuteNonQuery());
        }
Ejemplo n.º 3
0
        /// <summary>
        /// 将数据实体插到对应的数据库表中。
        /// </summary>
        /// <example>
        /// <para>下面的代码演示了Insert()方法的用法</para>
        /// <code>
        /// //Contract类需要继承自BaseEntity,并且需要放在以*.Entity.dll结尾的程序集中
        /// Contract contract = new Contract();
        ///
        /// contract.ContractGUID = Guid.NewGuid();
        /// contract.ContractName = "...";
        /// //...其他字段
        ///
        /// int count = contract.Insert();
        /// //插入成功后,count等于1
        /// </code>
        /// </example>
        /// <exception cref="InvalidOperationException">1.如果没有对实体类的任何一个字段赋值,就进行Insert()操作,则会抛出此异常2.类没有定义主键,即没有任何一个属性被标记为PrimaryKey=true,则抛出此异常</exception>
        /// <exception cref="InvalidProgramException">如果数据实体类型的定义不符合规范,就会抛出此异常</exception>
        /// <returns>返回ADO.NET的原始结果</returns>
        public virtual int Insert()
        {
            CPQuery query = GetCPQuery(3, new object[] { this });

            if (query == null)
            {
                throw new InvalidOperationException("传入对象不能生成有效的SQL语句。");
            }

            if (_funcBefore != null)
            {
                if (_funcBefore(query) == false)
                {
                    return(-1);
                }
            }

            return(query.ExecuteNonQuery());
        }
Ejemplo n.º 4
0
        /// <summary>
        /// 用并发检测的方式,更新数据实体对应的记录。
        /// </summary>
        /// <example>
        /// <para>下面的代码演示了并发检测模式下,Update()方法的用法</para>
        /// <code>
        /// <![CDATA[
        /// //Contract类需要继承自BaseEntity,并且需要放在以*.Entity.dll结尾的程序集中
        ///
        /// public void Load(){
        ///
        ///     //在页面加载时,查询数据库信息,时间戳字段需要通过CAST转换为长整型,绑定到界面中
        ///     Contract contract = CPQuery.From("SELECT ContractGUID, CAST(ContractVersion AS BigInt) ContractVersion  .... FROM cb_Contract WHERE ...").ToSingle<Contract>();
        ///
        ///     //其他数据绑定代码
        ///     //...
        /// }
        ///
        /// public void Update(string dataXML, long contractVersion){
        ///		//将AppFrom的xml直接转换为实体对象
        ///		Contract contract = XmlDataEntity.ConvertXmlToSingle<CbContract>(dataXML)
        ///
        ///		//构造用于并发检测的原对象
        ///		Contract origContract = new Contract();
        ///		origContract.ContractGUID = contract.ContractGUID; //并发检测时,原对象的主键是必须提供的
        ///		contract.ContractVersion = contractVersion.Int64ToTimeStamp(); //界面中长整型的时间戳字段可以通过Int64ToTimeStamp扩展方法转换为byte[]数组
        ///
        ///		try{
        ///			//根据时间戳字段,进行并发检测
        ///			int count = contract.Update(origContract, ConcurrencyMode.TimeStamp);
        ///			//如果更新成功,则count为1
        ///
        ///			//根据原始值,进行并发检测
        ///			//count = contract.Update(origContract, ConcurrencyMode.OriginalValue);
        ///		}
        ///		catch(OptimisticConcurrencyException ex){
        ///			//并发检测失败,将会抛出OptimisticConcurrencyException异常
        ///		}
        /// }
        /// ]]>
        /// </code>
        /// </example>
        /// <param name="original">用于并发检测的原始对象</param>
        /// <param name="concurrencyMode">并发检测模式</param>
        /// <exception cref="InvalidProgramException">如果数据实体类型的定义不符合规范,就会抛出此异常</exception>
        /// <exception cref="InvalidOperationException">类没有定义主键,即没有任何一个属性被标记为PrimaryKey=true,则抛出此异常</exception>
        /// <exception cref="ArgumentException">用于并发检测的原始对象不能是当前对象</exception>
        /// <exception cref="Hack.Fast.Extensions.Exception.OptimisticConcurrencyException">并发检测失败时,则会抛出此异常</exception>
        /// <returns>返回ADO.NET的原始结果</returns>
        public virtual int Update(BaseEntity original, ConcurrencyMode concurrencyMode)
        {
            if (original == null)
            {
                throw new ArgumentNullException("original");
            }


            if (concurrencyMode == ConcurrencyMode.OriginalValue && object.ReferenceEquals(this, original))
            {
                throw new ArgumentException("用于并发检测的原始对象不能是当前对象。");
            }

            int     flag  = concurrencyMode == ConcurrencyMode.TimeStamp ? 8 : 9;
            CPQuery query = GetCPQuery(flag, new object[] { this, original, bakObject });

            if (query == null)
            {
                return(0);
            }

            if (_funcBefore != null)
            {
                if (_funcBefore(query) == false)
                {
                    return(-1);
                }
            }

            int effectRows = query.ExecuteNonQuery();

            if (effectRows == 0)
            {
                throw new Hack.Fast.Extensions.OptimisticConcurrencyException(
                          "并发操作失败,本次操作没有更新任何记录,请确认当前数据行没有被其他用户更新或删除。");
            }

            return(effectRows);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// 用并发检测的方式,将数据实体对应的记录从数据库表中删除。
        /// </summary>
        /// <example>
        /// <para>下面的代码演示了并发检测模式下,Delete()方法的用法</para>
        /// <code>
        /// <![CDATA[
        /// //Contract类需要继承自BaseEntity,并且需要放在以*.Entity.dll结尾的程序集中
        ///
        /// public void Load(){
        ///
        ///     //在页面加载时,查询数据库信息,时间戳字段需要通过CAST转换为长整型,绑定到界面中
        ///     Contract contract = CPQuery.From("SELECT ContractGUID, CAST(ContractVersion AS BigInt) ContractVersion  .... FROM cb_Contract WHERE ...").ToSingle<Contract>();
        ///
        ///     //其他数据绑定代码
        ///     //...
        /// }
        ///
        /// //删除通道,前端需要传递合同GUID,时间戳字段
        /// public void Delete(Guid contractGUID, long contractVersion){
        ///
        ///		//删除动作,需要构建一个实体对象
        ///		Contract contract = new Contract();
        ///		contract.ContractGUID = contractGUID; //主键必须赋值,这是删除语句的首要条件
        ///		contract.ContractVersion = contractVersion.Int64ToTimeStamp(); //界面中长整型的时间戳字段可以通过Int64ToTimeStamp扩展方法转换为byte[]数组
        ///
        ///		try{
        ///			//根据时间戳字段,进行并发检测
        ///			int count = contract.Delete(ConcurrencyMode.TimeStamp);
        ///			//如果删除成功,则count为1
        ///
        ///			//根据原始值,进行并发检测
        ///			//count = contract.Delete(oldContract, ConcurrencyMode.OriginalValue);
        ///		}
        ///		catch(OptimisticConcurrencyException ex){
        ///			//并发检测失败,将会抛出OptimisticConcurrencyException异常
        ///		}
        /// }
        /// ]]>
        /// </code>
        /// </example>
        /// <exception cref="InvalidProgramException">如果数据实体类型的定义不符合规范,就会抛出此异常</exception>
        /// <exception cref="InvalidOperationException">类没有定义主键,即没有任何一个属性被标记为PrimaryKey=true,则抛出此异常</exception>
        /// <exception cref="Hack.Fast.Extensions.Exception.OptimisticConcurrencyException">并发检测失败时,则会抛出此异常</exception>
        /// <param name="concurrencyMode">并发检测模式</param>
        /// <returns>返回ADO.NET的原始结果</returns>
        public virtual int Delete(ConcurrencyMode concurrencyMode)
        {
            int     flag  = concurrencyMode == ConcurrencyMode.TimeStamp ? 5 : 6;
            CPQuery query = GetCPQuery(flag, new object[] { this });

            if (_funcBefore != null)
            {
                if (_funcBefore(query) == false)
                {
                    return(-1);
                }
            }

            int effectRows = query.ExecuteNonQuery();

            if (effectRows == 0)
            {
                throw new Hack.Fast.Extensions.OptimisticConcurrencyException(
                          "并发操作失败,本次操作没有删除任何记录,请确认当前数据行没有被其他用户更新或删除。");
            }

            return(effectRows);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// 立即提交所有的操作请求
        /// 如果需要事务支持,请用using(ConnectionScope)的方式来实现
        /// </summary>
        public void Submit()
        {
            foreach (DBExecuteInfo info in _list)
            {
                if (info.FuncBefore != null)
                {
                    CPQuery query = info.DBExecute as CPQuery;
                    if (info.FuncBefore(query) == false)
                    {
                        continue;
                    }
                }

                int effectRows = info.DBExecute.ExecuteNonQuery();

                if (info.Concurrency && effectRows == 0)
                {
                    throw new Hack.Fast.Extensions.OptimisticConcurrencyException(
                              "并发操作失败,本次操作没有更新任何记录,请确认当前数据行没有被其他用户更新或删除。");
                }
            }

            _list.Clear();
        }
Ejemplo n.º 7
0
        /// <summary>
        /// 根据PagingInfo信息,返回分页后的实体集合
        /// </summary>
        /// <typeparam name="T">实体类型</typeparam>
        /// <param name="pageInfo">分页信息</param>
        /// <returns>实体集合</returns>
        public List <T> ToPageList <T>(PagingInfo pageInfo) where T : class, new()
        {
            //--需要配置的SQL语句
            //select row_number() over (order by UpCount asc) as RowIndex,
            //    Title, Tag, [Description], Creator, CreateTime, UpCount, ReadCount, ReplyCount
            //from   CaoItem
            //where CreateTime < @CreateTime

            //--在运行时,将会生成下面二条SQL

            //select * from (
            //select row_number() over (order by UpCount asc) as RowIndex,
            //    Title, Tag, [Description], Creator, CreateTime, UpCount, ReadCount, ReplyCount
            //from   CaoItem
            //where CreateTime < @CreateTime
            //) as t1
            //where  RowIndex > (@PageSize * @PageIndex) and RowIndex <= (@PageSize * (@PageIndex+1))

            //select  count(*) from   ( select
            //-- 去掉 select row_number() over (order by UpCount asc) as RowIndex,
            //    Title, Tag, [Description], Creator, CreateTime, UpCount, ReadCount, ReplyCount
            //from   CaoItem as p
            //where CreateTime < @CreateTime
            //) as t1


            // 为了方便得到 count 的语句,先直接定位 ") as RowIndex,"
            // 然后删除这之前的部分,将 select  count(*) from   (select 加到SQL语句的前面。
            // 所以,这里就检查SQL语句是否符合要求。

            //string flag = ") as RowIndex,";
            //int p = xmlCommandText.IndexOf(flag, StringComparison.OrdinalIgnoreCase);
            //if( p <= 0 )
            //    throw new InvalidOperationException("XML中配置的SQL语句不符合分页语句的要求。");

            string xmlCommandText = _query.ToString();

            Match match = _pagingRegex.Match(xmlCommandText);

            if (match.Success == false)
            {
                throw new InvalidOperationException("XML中配置的SQL语句不符合分页语句的要求。");
            }
            int p = match.Index;


            // 获取命令参数数组
            SqlParameter[] parameters1 = _query.Command.Parameters.Cast <SqlParameter>().ToArray();
            _query.Command.Parameters.Clear();                  // 断开参数对象与原命令的关联。

            // 克隆参数数组,因为参数对象只能属于一个命令对象。
            SqlParameter[] parameters2 = (from pp in parameters1
                                          select new SqlParameter {
                ParameterName = pp.ParameterName,
                SqlDbType = pp.SqlDbType,
                Size = pp.Size,
                Scale = pp.Scale,
                Value = pp.Value,
                Direction = pp.Direction
            }).ToArray();



            // 生成 SELECT 命令
            string selectCommandText = string.Format(@"select * from ( {0} ) as t1 
where  RowIndex > (@PageSize * @PageIndex) and RowIndex <= (@PageSize * (@PageIndex+1))", xmlCommandText);

            CPQuery query1 = CPQuery.From(selectCommandText, parameters1);

            query1.Command.Parameters.Add(new SqlParameter {
                ParameterName = "@PageIndex",
                SqlDbType     = System.Data.SqlDbType.Int,
                Value         = pageInfo.PageIndex
            });
            query1.Command.Parameters.Add(new SqlParameter {
                ParameterName = "@PageSize",
                SqlDbType     = System.Data.SqlDbType.Int,
                Value         = pageInfo.PageSize
            });



            // 生成 COUNT 命令
            string getCountText = string.Format("select  count(*) from   (select {0}  ) as t1",
                                                xmlCommandText.Substring(p + match.Length));

            CPQuery query2 = CPQuery.From(getCountText, parameters2);


            // 执行二次数据库操作(在一个连接中)
            using (ConnectionScope scope = new ConnectionScope()) {
                List <T> list = query1.ToList <T>();
                pageInfo.TotalRecords = query2.ExecuteScalar <int>();

                return(list);
            }
        }