Ejemplo n.º 1
0
        private static T BuildItem <T>(SqliteDataReader reader, FieldInfo[] fieldInfos, PropertyInfo[] propertyInfos) where T : class, new()
        {
            T item = new T();

            foreach (FieldInfo field in fieldInfos)
            {
                DbFieldAttribute dbFieldAttr = GetDbFieldAttribute(field);
                if (dbFieldAttr == null)
                {
                    continue;
                }

                object v = GetValue(reader, field.FieldType, dbFieldAttr);

                field.SetValue(item, v);
            }

            foreach (PropertyInfo property in propertyInfos)
            {
                DbFieldAttribute dbFieldAttr = GetDbFieldAttribute(property);
                if (dbFieldAttr == null)
                {
                    continue;
                }

                object v = GetValue(reader, property.PropertyType, dbFieldAttr);

                property.SetValue(item, v, null);
            }

            return(item);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// 从数据库中删除一条记录
        /// </summary>
        public static async Task DeleteEntity <T>(DbConnector connector, int id) where T : new()
        {
            Type entityType = typeof(T);

            if (!(DbTableAttribute.GetCustomAttribute(entityType, typeof(DbTableAttribute)) is DbTableAttribute tableAttr))
            {
                throw new Exception("类型" + entityType.FullName + "没有标记DbTableAttribute特性");
            }

            string tableName  = tableAttr.TableName;
            string primaryKey = string.Empty;

            foreach (PropertyInfo property in entityType.GetProperties())
            {
                if (!property.IsDefined(typeof(DbFieldAttribute), false))
                {
                    continue;
                }

                DbFieldAttribute fldAttr = (DbFieldAttribute)(Attribute.GetCustomAttribute(property, typeof(DbFieldAttribute)));
                if (fldAttr.IsPrimaryKey)
                {
                    primaryKey = fldAttr.FieldName;
                }
            }
            if (string.IsNullOrEmpty(tableName) || string.IsNullOrEmpty(primaryKey))
            {
                throw new Exception("类型" + entityType.FullName + "不支持数据库操纵");
            }
            await DeleteEntity(connector, tableName, primaryKey, id);
        }
Ejemplo n.º 3
0
        static SqlParameter GenerateSqlParameter(DbFieldAttribute fldAttr, Type memberType, object value)
        {
            string parameterName = "@" + fldAttr.FieldName;

            if (value != null)
            {
                if (fldAttr.FieldType == SqlDbType.BigInt ||
                    fldAttr.FieldType == SqlDbType.Int ||
                    fldAttr.FieldType == SqlDbType.SmallInt ||
                    fldAttr.FieldType == SqlDbType.TinyInt ||
                    fldAttr.FieldType == SqlDbType.UniqueIdentifier ||
                    fldAttr.FieldType == SqlDbType.Xml
                    )
                {
                    SqlParameter p = new SqlParameter(parameterName, fldAttr.FieldType)
                    {
                        Value = value
                    };
                    return(p);
                }
                else
                {
                    return(new SqlParameter(parameterName, value));
                }
            }
            else
            {
                SqlDbType dbType = (fldAttr.TypeDefined)? fldAttr.FieldType: ValueHelper.MapSystemTypeToSqlDbType(memberType);
                return(new SqlParameter(parameterName, dbType)
                {
                    Value = DBNull.Value
                });
            }
        }
Ejemplo n.º 4
0
 internal DbColumnMapping(PropertyInfo property, DbFieldAttribute attr)
 {
     this.FieldAttribute      = attr;
     this.Property            = property;
     this.ColumnType          = property.PropertyType;
     this.ColumnName          = attr.FieldName ?? property.Name;
     this.PrimaryKeyAttribute = property.GetCustomAttribute <DbFieldPrimaryKeyAttribute>();
 }
Ejemplo n.º 5
0
 internal DbColumnMapping(FieldInfo field, DbFieldAttribute attr)
 {
     this.FieldAttribute      = attr;
     this.Field               = field;
     this.ColumnType          = field.FieldType;
     this.ColumnName          = attr.FieldName ?? field.Name;
     this.PrimaryKeyAttribute = field.GetCustomAttribute <DbFieldPrimaryKeyAttribute>();
 }
Ejemplo n.º 6
0
        /// <summary>
        /// 从一个对象实例中通过检查DbTable和DbField特性来构建一个用于插入数据行的T-SQL语句。
        /// 为了防止SQL注入,该SQL语句是参数化的,并且通过out参数返回由entity对象实例中包括的值构建出来的SqlParameter集
        /// </summary>
        /// <param name="entity">准备用作插入新行的对象实例</param>
        /// <param name="parameters">参数化的每一列输入参数,包含了值</param>
        /// <param name="primaryKey">主键输出参数,用来返回新行的主键</param>
        /// <returns></returns>
        static string BuildInsertSql(object entity, out SqlParameter[] parameters, out SqlParameter primaryKey)
        {
            Type type = entity.GetType();

            object[] tableAttributes = type.GetCustomAttributes(typeof(DbTableAttribute), false);
            if (tableAttributes == null || tableAttributes.Length != 1)
            {
                throw new Exception("使用BuildInsertSql()方法,类" + type.FullName + "必须标记唯一的DbTable特性。");
            }

            DbTableAttribute tableAttr = (DbTableAttribute)tableAttributes[0];

            StringBuilder       fieldBuilder = new StringBuilder(), valueBuilder = new StringBuilder();
            List <SqlParameter> parametersList = new List <SqlParameter>();

            primaryKey = null;
            foreach (MemberInfo m in type.GetMembers(BindingFlags.Instance | BindingFlags.Public))
            {
                #region loop values
                bool isDefine = m.IsDefined(typeof(DbFieldAttribute), false);
                if (!isDefine)
                {
                    continue;
                }

                DbFieldAttribute fldAttr = (DbFieldAttribute)(DbFieldAttribute.GetCustomAttribute(m, typeof(DbFieldAttribute)));
                if (fldAttr.IsPrimaryKey)
                {
                    primaryKey = new SqlParameter("@" + fldAttr.FieldName, SqlDbType.Int)
                    {
                        Direction = ParameterDirection.Output
                    };
                    parametersList.Add(primaryKey);
                    continue;
                }

                if ((fldAttr.Usage & DbFieldUsage.InsertParameter) != DbFieldUsage.InsertParameter)
                {
                    continue;
                }

                fieldBuilder.Append(",[" + fldAttr.FieldName + "]");
                valueBuilder.Append(",@" + fldAttr.FieldName);

                Type         memberType;
                object       memberValue = ValueHelper.GetMemberValue(m, fldAttr, entity, out memberType);
                SqlParameter parameter   = GenerateSqlParameter(fldAttr, memberType, memberValue);
                parametersList.Add(parameter);
                #endregion
            }
            fieldBuilder.Remove(0, 1);
            valueBuilder.Remove(0, 1);

            string sql = @$ "
INSERT INTO {tableAttr.TableName}({fieldBuilder.ToString()}) VALUES({valueBuilder.ToString()});
Ejemplo n.º 7
0
        /// <summary>
        /// 从实体对象中读取属性或字段值,用于给SqlParameter参数设置正确的值。
        /// 尤其是对IsForeignKey(负数或0)和DateTime类型的值(早于1900-01-01),设置DbNull.Value给参数
        /// </summary>
        /// <param name="member"></param>
        /// <param name="attr"></param>
        /// <param name="entity"></param>
        /// <param name="dataType"></param>
        /// <returns></returns>
        public static object GetMemberValue(MemberInfo member, DbFieldAttribute attr, object entity, out Type dataType)
        {
            object obj;

            if (member.MemberType == MemberTypes.Field)
            {
                FieldInfo field = (FieldInfo)member;
                dataType = field.FieldType;
                obj      = field.GetValue(entity);
            }
            else if (member.MemberType == MemberTypes.Property)
            {
                PropertyInfo property = (PropertyInfo)member;
                dataType = property.PropertyType;
                obj      = property.GetValue(entity, null);
            }
            else
            {
                throw new Exception("必须是字段或者属性。");
            }

            if (attr.IsForeignKey)
            {
                if (attr.FieldType == SqlDbType.BigInt ||
                    attr.FieldType == SqlDbType.Int ||
                    attr.FieldType == SqlDbType.SmallInt ||
                    attr.FieldType == SqlDbType.TinyInt
                    )
                {
                    if (Convert.ToInt32(obj) <= 0)
                    {
                        return(null);
                    }
                }
            }

            if (dataType.ToString() == "System.DateTime")
            {
                if ((DateTime)obj <= new DateTime(1900, 1, 1))
                {
                    return(null);
                }
            }

            return(obj);
        }
Ejemplo n.º 8
0
        private static List <Tuple <PropertyInfo, DbFieldAttribute> > GetPropertyCache(Type t)
        {
            if (propertyCache.ContainsKey(t))
            {
                return(propertyCache[t].ToList()); // always return a copy
            }
            List <Tuple <PropertyInfo, DbFieldAttribute> > newValue = new List <Tuple <PropertyInfo, DbFieldAttribute> >();
            var properties = t.GetProperties().Where(prop => prop.IsDefined(typeof(DbFieldAttribute), false));

            foreach (var p in properties)
            {
                DbFieldAttribute f = p.GetAttributeOfType <DbFieldAttribute>();
                newValue.Add(new Tuple <PropertyInfo, DbFieldAttribute>(p, f));
            }

            propertyCache.Add(t, newValue);
            return(newValue);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// 使用关键字id从数据库中查找,返回entityType类的实例
        /// </summary>
        /// <param name="connector"></param>
        /// <param name="entityType"></param>
        /// <param name="id"></param>
        /// <returns></returns>
        public static async Task <T> FindEntity <T>(DbConnector connector, int id) where T : new()
        {
            Type entityType = typeof(T);

            object[] tableAttributes = entityType.GetCustomAttributes(typeof(DbTableAttribute), false);
            if (tableAttributes == null || tableAttributes.Length != 1)
            {
                throw new Exception("使用FindEntity()方法,类" + entityType.FullName + "必须标记唯一的DbTable特性。");
            }

            DbTableAttribute tableAttr = (DbTableAttribute)tableAttributes[0];
            string           tableName = tableAttr.TableName;
            string           keyName   = string.Empty;

            foreach (PropertyInfo propertyInfo in entityType.GetProperties())
            {
                if (!propertyInfo.IsDefined(typeof(DbFieldAttribute), false))
                {
                    continue;
                }

                DbFieldAttribute fldAttr = (DbFieldAttribute)(DbFieldAttribute.GetCustomAttribute(propertyInfo, typeof(DbFieldAttribute)));
                if (fldAttr.IsPrimaryKey)
                {
                    keyName = fldAttr.FieldName;
                    break;
                }
            }

            string sql = string.Format(@"SELECT * FROM {0} WHERE {1}={2};", tableName, keyName, id);

            DataTable table = await connector.ExecuteSqlQueryTable(sql);

            if (table == null || table.Rows.Count == 0)
            {
                return(default(T));
            }
            else
            {
                object obj = Activator.CreateInstance(entityType);
                ValueHelper.FulfillEntity(entityType, table.Rows[0], ref obj);
                return((T)obj);
            }
        }
Ejemplo n.º 10
0
        /// <summary>
        /// 使用row中的值填充对象entity
        /// </summary>
        /// <param name="type"></param>
        /// <param name="row"></param>
        /// <param name="entity"></param>
        public static void FulfillEntity(Type type, DataRow row, ref object entity)
        {
            foreach (MemberInfo m in type.GetMembers(BindingFlags.Instance | BindingFlags.Public))
            {
                Attribute attr = DbFieldAttribute.GetCustomAttribute(m, typeof(DbFieldAttribute));
                if (attr == null)
                {
                    continue;
                }

                DbFieldAttribute dAttr = (DbFieldAttribute)attr;
                if ((dAttr.Usage & DbFieldUsage.MapResultTable) != DbFieldUsage.MapResultTable)
                {
                    continue;
                }

                try
                {
                    if (m.MemberType == MemberTypes.Field)
                    {
                        //the member is a DbField;
                        object value = ValueHelper.GetTableRowValue(row, dAttr.FieldName, ((FieldInfo)m).FieldType);
                        ((FieldInfo)m).SetValue(entity, value);
                    }
                    else if (m.MemberType == MemberTypes.Property)
                    {
                        //the member is a DbField;
                        object value = GetTableRowValue(row, dAttr.FieldName, ((PropertyInfo)m).PropertyType);
                        ((PropertyInfo)m).SetValue(entity, value, null);
                    }
                }
                catch (Exception ex)
                {
                    throw new Exception("成员[" + m.Name + "]出错" + ex.ToString());
                }
            }
        }
Ejemplo n.º 11
0
    protected void _AnalyseDbClz(int rowCount, Func <Type, int, object> getNextElement)
    {
        FieldInfo[]      fieldInfos = GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
        FieldInfo        info       = null;
        DbFieldAttribute attr       = null;

        for (int i = 0; i < fieldInfos.Length; ++i)
        {
            info = fieldInfos[i];
            attr = Attribute.GetCustomAttribute(info, typeof(DbFieldAttribute), true) as DbFieldAttribute;
            if (attr == null || attr.FieldType == DbFieldType.None)
            {
                continue;
            }
            object sequenceData = null;

            switch (attr.FieldType)
            {
            case DbFieldType.Array:
                sequenceData = DataImporter.GenArray(info.FieldType, rowCount,
                                                     idx => getNextElement(DataImporter.GetArrayElementType(info.FieldType), idx));

                break;

            case DbFieldType.List:
                sequenceData = DataImporter.GenList(info.FieldType, rowCount,
                                                    idx => getNextElement(DataImporter.GetGenericListElementType(info.FieldType), idx));

                break;

            default:
                continue;
            }

            info.SetValue(this, sequenceData);
        }
    }
Ejemplo n.º 12
0
        public sys_log EntityFields <T>(T entity)
        {
            sys_log slog = new sys_log();
            Dictionary <string, object> fields = new Dictionary <string, object>();
            Type type = entity.GetType();

            slog.tablename = type.Name;
            PropertyInfo[] proinfos = type.GetProperties();
            foreach (var item in proinfos)
            {
                string colname = string.Empty;
                object colval  = null;
                var    attrs   = item.GetCustomAttributes(typeof(DbFieldAttribute));
                if (attrs.Count() > 0)
                {
                    DbFieldAttribute attr = attrs.First() as DbFieldAttribute;
                    colname = attr.FieldName;
                    colval  = item.GetValue(entity);
                    fields.Add(colname, colval);
                }
            }
            slog.fields = fields.Where(t => t.Value != null).ToDictionary(t => t.Key, t => t.Value);
            StringBuilder cols = new StringBuilder();
            StringBuilder vals = new StringBuilder();

            slog.fields.ToList().ForEach(t => cols.Append(t.Key + ","));
            slog.fields.ToList().ForEach(t => vals.Append($"'{t.Value}',"));
            StringBuilder sql = new StringBuilder();

            sql.Append("select ");
            sql.Append(cols.ToString().Substring(0, cols.Length - 1));
            sql.Append($" from {slog.tablename} where id = :id ");
            slog.querysql  = sql.ToString();
            slog.insertsql = $"insert into {slog.tablename} ({cols.ToString().Substring(0, cols.Length - 1)}) values ({vals.ToString().Substring(0, vals.Length - 1)})";
            return(slog);
        }
Ejemplo n.º 13
0
        static object GetValue(SqliteDataReader reader, System.Type fieldType, DbFieldAttribute attr)
        {
            object v = null;

            if (fieldType == typeof(int))
            {
                v = Db.GetInt(reader, attr.FieldName);
            }
            else if (fieldType == typeof(int[]))
            {
                v = PETools.Db.GetIntArray(reader, attr.FieldName);
            }
            else if (fieldType == typeof(float))
            {
                v = Db.GetFloat(reader, attr.FieldName);
            }
            else if (fieldType == typeof(float[]))
            {
                v = PETools.Db.GetFloatArray(reader, attr.FieldName);
            }
            else if (fieldType == typeof(string))
            {
                v = Db.GetString(reader, attr.FieldName);
            }
            else if (fieldType == typeof(bool))
            {
                v = Db.GetBool(reader, attr.FieldName);
            }
            else if (fieldType == typeof(Color))
            {
                v = Db.GetColor(reader, attr.FieldName);
            }
            else if (fieldType.IsEnum)
            {
                if (attr.EnumValue)
                {
                    v = Db.GetInt(reader, attr.FieldName);
                }
                else
                {
                    v = System.Enum.Parse(fieldType, Db.GetString(reader, attr.FieldName));
                }
            }
            else if (fieldType == typeof(Vector3))
            {
                v = PETools.Db.GetVector3(reader, attr.FieldName);
            }
            else if (fieldType == typeof(Vector3[]))
            {
                v = PETools.Db.GetVector3Array(reader, attr.FieldName);
            }
            else if (fieldType == typeof(Quaternion))
            {
                v = PETools.Db.GetQuaternion(reader, attr.FieldName);
            }
            else if (fieldType == typeof(Quaternion[]))
            {
                v = PETools.Db.GetQuaternionArray(reader, attr.FieldName);
            }
            else
            {
                Debug.LogError("not supported value type:" + fieldType);
            }
            return(v);
        }
Ejemplo n.º 14
0
        private static T BuildListItem <T>(SQLiteDataReader reader, FieldInfo[] fieldInfos, PropertyInfo[] propertyInfos,
                                           int cacheId = 0) where T : class, new()
        {
            if (cacheId == 0 || cacheId != attrTEMP)
            {
                dbFieldAttrTEMP    = null;
                dbPropertyAttrTEMP = null;
            }

            attrTEMP = cacheId;

            T item = new T();

            for (int i = 0; i < fieldInfos.Length; i++)
            {
                var field = fieldInfos[i];
                if (dbFieldAttrTEMP == null)
                {
                    dbFieldAttrTEMP = new List <DbFieldAttribute>(8);
                }

                if (dbFieldAttrTEMP.Count < fieldInfos.Length)
                {
                    DbFieldAttribute dbFieldAttr = GetDbFieldAttribute(field);
                    dbFieldAttrTEMP.Add(dbFieldAttr);
                }

                var atrr = dbFieldAttrTEMP[i];
                if (atrr == null)
                {
                    continue;
                }

                object v = GetValue(reader, field.FieldType, atrr);

                field.SetValue(item, v);
            }

            for (int i = 0; i < propertyInfos.Length; i++)
            {
                var property = propertyInfos[i];

                if (dbPropertyAttrTEMP == null)
                {
                    dbPropertyAttrTEMP = new List <DbFieldAttribute>(8);
                }

                if (dbPropertyAttrTEMP.Count < fieldInfos.Length)
                {
                    DbFieldAttribute dbPropertyttr = GetDbFieldAttribute(property);
                    dbPropertyAttrTEMP.Add(dbPropertyttr);
                }

                var atrr = dbPropertyAttrTEMP[i];
                if (atrr == null)
                {
                    continue;
                }

                object v = GetValue(reader, property.PropertyType, atrr);

                property.SetValue(item, v, null);
            }

            return(item);
        }
Ejemplo n.º 15
0
        private static object GetValue(SQLiteDataReader reader, System.Type fieldType, DbFieldAttribute attr)
        {
            object v = null;

            if (fieldType == typeof(int))
            {
                v = Converter.ToInt(reader, attr.FieldName);
            }
            else if (fieldType == typeof(byte))
            {
                v = (byte)Converter.ToInt(reader, attr.FieldName);
            }
            else if (fieldType == typeof(float))
            {
                v = Converter.ToFloat(reader, attr.FieldName);
            }
            else if (fieldType == typeof(string))
            {
                v = Converter.ToString(reader, attr.FieldName);
            }
            else if (fieldType == typeof(bool))
            {
                v = Converter.ToBool(reader, attr.FieldName);
            }
            else if (fieldType == typeof(Vector3))
            {
                v = Converter.ToVector3(reader, attr.FieldName, attr.Separator);
            }
            else if (fieldType == typeof(Vector2))
            {
                v = Converter.ToVector2(reader, attr.FieldName, attr.Separator);
            }
            else if (fieldType.IsEnum)
            {
                v = System.Enum.Parse(fieldType, Converter.ToString(reader, attr.FieldName));
            }
            else if (fieldType == typeof(int[]))
            {
                v = Converter.GetIntArray(reader, attr.FieldName, attr.Separator);
            }
            else if (fieldType == typeof(float[]))
            {
                v = Converter.ToFloatArray(reader, attr.FieldName, attr.Separator);
            }
            else if (fieldType == typeof(string[]))
            {
                v = Converter.ToStringArray(reader, attr.FieldName, attr.Separator);
            }
            else
            {
                Debug.LogError("not supported value type:" + fieldType);
            }

            return(v);
        }
Ejemplo n.º 16
0
        public void UpdateLog <T>(T entity, T orginalobj)
        {
            if (!islog)
            {
                return;
            }
            object        id   = 0;
            StringBuilder txt  = new StringBuilder();
            sys_log       slog = EntityFields <T>(entity);

            slog.fields.TryGetValue("id", out id);
            sys_user user = CacheManager.Instance().Current_User;

            txt.Append($"[{user.name}]更新{slog.tablename},");
            var  cnames  = slog.fields.Select(t => t.Key);
            Type orgtype = orginalobj.GetType();

            PropertyInfo[] orgproinfos = orgtype.GetProperties().Where(t => cnames.Contains(t.Name)).ToArray();
            foreach (var item in orgproinfos)
            {
                string fn       = string.Empty;
                object fv       = null;
                object fvnew    = null;
                var    orgattrs = item.GetCustomAttributes(typeof(DbFieldAttribute));
                if (orgattrs.Count() > 0)
                {
                    DbFieldAttribute attr = orgattrs.First() as DbFieldAttribute;
                    fn = attr.FieldName;
                    fv = item.GetValue(orginalobj);
                    string coltype = item.PropertyType.Name;
                    slog.fields.TryGetValue(fn, out fvnew);
                    switch (coltype)
                    {
                    case "Int32":
                        if (Convert.ToInt32(fv) != Convert.ToInt32(fvnew ?? 0))
                        {
                            txt.Append($"[{attr.Label}]:{fv}->{fvnew},");
                        }
                        break;

                    case "String":
                        if (fv.ToString() != (fvnew ?? "").ToString())
                        {
                            txt.Append($"[{attr.Label}]:{fv}->{fvnew},");
                        }
                        break;

                    case "DateTime":
                        if (Convert.ToDateTime(fv) != Convert.ToDateTime(fvnew))
                        {
                            txt.Append($"[{attr.Label}]:{fv}->{fvnew},");
                        }
                        break;

                    case "Double":
                        if (Convert.ToDouble(fv) != Convert.ToDouble(fvnew ?? 0))
                        {
                            txt.Append($"[{attr.Label}]:{fv}->{fvnew},");
                        }
                        break;

                    case "Float":
                        if (Convert.ToSingle(fv) != Convert.ToSingle(fvnew ?? 0))
                        {
                            txt.Append($"[{attr.Label}]:{fv}->{fvnew},");
                        }
                        break;

                    case "Decimal":
                        if (Convert.ToDecimal(fv) != Convert.ToDecimal(fvnew ?? 0))
                        {
                            txt.Append($"[{attr.Label}]:{fv}->{fvnew},");
                        }
                        break;

                    default:
                        break;
                    }
                }
            }
            log.Info(txt.ToString());
        }
Ejemplo n.º 17
0
        /// <summary>
        /// 使用提供的条件查询数据库(表由entityType指定),返回满足条件的记录(分页)
        /// </summary>
        /// <typeparam name="T">要查询的实体类型,标记了DbTable和DbField特性的类,并且具有空白构造函数</typeparam>
        /// <param name="connector"></param>
        /// <param name="criteria">查询条件字典,键是PropertyName,条件仅支持=比较,条件间仅支持AND运算</param>
        /// <param name="pageIndex">从0开始的返回页索引</param>
        /// <param name="pageSize">每页几行记录</param>
        /// <param name="sortProperty">用于排序的PropertyName(如为空则使用关键字)</param>
        /// <param name="descending">是否倒序排列</param>
        /// <param name="total">符合条件的记录总数</param>
        /// <returns></returns>
        public static async Task <PagedQuery <T> > SearchEntities <T>(DbConnector connector, Dictionary <string, object> criteria,
                                                                      int pageIndex, int pageSize, string sortProperty, bool descending) where T : new()
        {
            Type entityType = typeof(T);

            if (!(DbTableAttribute.GetCustomAttribute(entityType, typeof(DbTableAttribute)) is DbTableAttribute tableAttr))
            {
                throw new Exception("类型" + entityType.FullName + "没有标记DbTableAttribute特性");
            }

            string selectClause = "SELECT * ";
            string fromClause   = "FROM " + tableAttr.TableName;
            string orderBy;

            #region 正确处理orderBy
            DbFieldAttribute sortFieldAttr = null;
            if (string.IsNullOrWhiteSpace(sortProperty))
            {
                //如果没有传递sortProperty参数, 则使用PrimaryKey
                foreach (PropertyInfo property in entityType.GetProperties())
                {
                    DbFieldAttribute fldAttr = DbFieldAttribute.GetCustomAttribute(property, typeof(DbFieldAttribute)) as DbFieldAttribute;
                    if (fldAttr != null && fldAttr.IsPrimaryKey)
                    {
                        sortFieldAttr = fldAttr;
                        break;
                    }
                }
            }
            else
            {
                PropertyInfo property = entityType.GetProperty(sortProperty);
                if (property == null)
                {
                    throw new Exception(string.Format("类型{0}中没有找到{1}属性用于排序", entityType.FullName, sortProperty));
                }
                sortFieldAttr = DbFieldAttribute.GetCustomAttribute(property, typeof(DbFieldAttribute)) as DbFieldAttribute;
            }
            if (sortFieldAttr == null)
            {
                throw new Exception("类型" + entityType.FullName + "没有标记IsPrimaryKey=true的DbField特性");
            }

            if (descending)
            {
                orderBy = sortFieldAttr.FieldName + " DESC";
            }
            else
            {
                orderBy = sortFieldAttr.FieldName;
            }
            #endregion

            StringBuilder       whereBuilder  = new StringBuilder();
            List <SqlParameter> sqlParameters = new List <SqlParameter>();
            if (criteria != null)
            {
                foreach (string conditionName in criteria.Keys)
                {
                    if (criteria[conditionName] == null || criteria[conditionName].ToString().Length == 0)
                    {
                        continue;
                    }

                    PropertyInfo conditionProperty = entityType.GetProperty(conditionName);
                    if (conditionProperty == null)
                    {
                        throw new Exception(string.Format("类型{0}中没有找到{1}属性用于查询条件", entityType.FullName, conditionName));
                    }
                    DbFieldAttribute conditionAttr = DbFieldAttribute.GetCustomAttribute(conditionProperty, typeof(DbFieldAttribute)) as DbFieldAttribute;
                    if (conditionAttr == null)
                    {
                        throw new Exception(string.Format("类型{0}的{1}属性没有标记DbFieldAttribute特性, 无法用于数据库查询",
                                                          entityType.FullName, conditionName));
                    }

                    SqlParameter parameter = GenerateSqlParameter(conditionAttr, conditionProperty.PropertyType, criteria[conditionName]);
                    sqlParameters.Add(parameter);
                    whereBuilder.AppendFormat("[{0}]=@{0} ", conditionAttr.FieldName);
                    whereBuilder.Append("AND ");
                }
            }
            if (whereBuilder.Length > 0)
            {
                whereBuilder.Remove(whereBuilder.Length - 4, 4);
            }

            string sql = BuildPagedSelectSql(selectClause, fromClause, whereBuilder.ToString(), orderBy, pageIndex, pageSize);

            DataSet ds = await connector.ExecuteSqlQuerySet(sql, sqlParameters.ToArray());

            PagedQuery <T> result = new PagedQuery <T>();
            if (ds != null && ds.Tables.Count == 2)
            {
                result.Total           = (int)ds.Tables[0].Rows[0][0];
                ds.Tables[1].TableName = "result";
                result.Records         = await Task.Run(() => ValueHelper.WrapEntities <T>(ds.Tables[1]));
            }
            else
            {
                result.Total   = 0;
                result.Records = new T[0];
            }
            ds.Dispose();
            return(result);
        }