Commits

Inside Zhou committed 55bb93f

封装DataTable并据此生成的数据对象中,DBNull类型的值全部生成为null。

Comments (0)

Files changed (3)

 			}
 		}
 
+		public DyObj() { }
+
+		public DyObj(IDictionary<string, object> dict) {
+			foreach(var kv in dict) {
+				this._dict[kv.Key.ToLower()] = kv.Value;
+			}
+		}
+
 		public bool ContainsAttr(string attr) {
 			return this._dict.ContainsKey(attr.ToLower());
 		}
 		}
 
 		public DyObj Diff(DyObj dy) {
-			var result = new DyObj();
-			foreach(var kv in MiscExtension.Diff(this._dict, dy._dict)) {
-				result._dict[kv.Key.ToLower()] = kv.Value;
-			}
-			return result;
+			return new DyObj(MiscExtension.Diff(this._dict, dy._dict));
 		}
 
 		/// <summary>

Sql/DbDataObjectExtension.cs

 		/// <summary>
 		/// 将DataRow转换成DyObj类型,以字段名作为成员属性名。忽略谓词函数返回false的列。
 		/// </summary>
-		public static DyObj ToDynamicObject(this DataRow row, Func<string, bool> predicate = null) {
+		public static DyObj ToDynamicObject(this DataRow row, Predicate<string> predicate = null) {
 			if(null == row) {
 				return null;
 			}
 			var i = new DyObj();
 			foreach(DataColumn col in row.Table.Columns) {
 				if(null == predicate || predicate(col.ColumnName)) {
-					i[col.ColumnName] = row[col];
+					i[col.ColumnName] = row[col] is DBNull ? null : row[col];
 				}
 			}
 
 "
 			, RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.IgnorePatternWhitespace | RegexOptions.ExplicitCapture);
 
-		static string _tbAliasPrefix = "t";
-
 		string _originalSQLTxt;
-		SqlHelper _sh;
 		string _relation;
 		string _alias;
 
 		decimal _limit = 0;
 		decimal _offset = 0;
 
-		public Func<string, QueryPlan> J;
 		public Func<dynamic, dynamic> RowHandler;
+		public SqlHelper Sql { get; private set; }
 		#endregion
 
 		/// <example>
 			}
 
 			this._originalSQLTxt = sql.Trim();
-			this._sh = sh;
+			this.Sql = sh;
 			this._Setup();
 		}
 
 		public DataTable GetDataTable() {
 			dynamic sql = _GenerateSQLObject(this);
-			var comm = this._sh.Init(sql.txt as string);
+			var comm = this.Sql.Init(sql.txt as string);
 			if(null != sql.parameters) {
 				comm.AddParameters((sql.parameters as List<DbParameter>).ToArray());
 			}
 
 		public decimal Count() {
 			dynamic sqlObj = _GenerateSQLObject(this);
-			DbCommand comm = this._sh.Init(string.Format("SELECT count(*) FROM ({0})", sqlObj.txt));
+			DbCommand comm = this.Sql.Init(string.Format("SELECT count(*) FROM ({0})", sqlObj.txt));
 			if(!ObjectHelper.IsNil(sqlObj.parameters)) {
 				comm.AddParameters((sqlObj.parameters as List<DbParameter>).ToArray());
 			}
 		}
 
 		void _Setup() {
-			dynamic parsedSqlObj = _ParseSql(this._originalSQLTxt, this._sh);
+			dynamic parsedSqlObj = _ParseSql(this._originalSQLTxt, this.Sql);
 			this._relation = parsedSqlObj.relation;
 			this._column = parsedSqlObj.column;
 			this._alias = parsedSqlObj.alias;
-
-			this.J = (joinName) => {
-				throw new NotImplementedException();
-			};
 		}
 
 		/// <summary>
 			foreach(var kv in queryPlan._column) {
 				dynamic col = kv.Value;
 				if(col._guid == guid) {
-					return string.IsNullOrEmpty(queryPlan._alias) ? _tbAliasPrefix + tbIndex : queryPlan._alias as string;
+					return _GenerateQueryPlanAlias(queryPlan, tbIndex);
 				}
 				else if(!ObjectHelper.IsNil(col["join"])) {
 					var c = _FindTableAlias(col.join.plan, guid, ++tbIndex);
 			var contextualColumns = new DyObj();
 			var columnClause = new StringBuilder();
 			var tbIndex = queryPlanIndexer;
-			var tbAlias = string.IsNullOrEmpty(queryPlan._alias) ? _tbAliasPrefix + tbIndex : (queryPlan._alias as string).Substr();
+			var tbAlias = _GenerateQueryPlanAlias(queryPlan, tbIndex);
 
 			foreach(var kv in queryPlan._column) {
 				dynamic c = kv.Value;
 			if(queryPlan._conditions.Count > 0) {
 				txt.Append("\nWHERE");
 				foreach(var cond in queryPlan._conditions) {
-					txt.AppendFormat(" {0} AND", _ParseCondition(cond, parameters, contextualColumns, queryPlan._sh.CreateParameter, ref conditionIndexer));
+					txt.AppendFormat(" {0} AND", _ParseCondition(cond, parameters, contextualColumns, queryPlan.Sql.CreateParameter, ref conditionIndexer));
 				}
 				txt.Remove(txt.Length - 4, 4);
 			}
 			return result;
 		}
 
+		static string _GenerateQueryPlanAlias(QueryPlan plan, int index) {
+			return string.IsNullOrEmpty(plan._alias) ? "t" + index : (plan._alias as string).Substr();
+		}
+
 		//参数guid由父级传递进来,用于判断当前被join的对象是否应为DBNull.Value。
 		static dynamic _ParseQueryResult(DataRow dr, QueryPlan queryPlan, int qpCount = 0, string guid = null) {
 			dynamic result = new DyObj();
-			var tbAlias = string.IsNullOrEmpty(queryPlan._alias) ? _tbAliasPrefix + qpCount : (queryPlan._alias as string).Substr();
+			var tbAlias = _GenerateQueryPlanAlias(queryPlan, qpCount);
 
 			foreach(var kv in queryPlan._column) {
 				dynamic c = kv.Value;
 				var colName = "{0}_{1}".Fmt(tbAlias, string.IsNullOrEmpty(c.alias) ? c.attr_name as string : (c.alias as string).Substr());
 				if(ObjectHelper.IsNil(c["join"])) {
 					if(!string.IsNullOrEmpty(guid) && c._guid == guid && ObjectHelper.IsNil(dr[colName])) {
-						return DBNull.Value;
+						return null;
 					}
-					result[c.attr_name] = dr[colName];
+					result[c.attr_name] = dr[colName] is DBNull ? null : dr[colName];
 				}
 				else {
 					result[c.attr_name] = _ParseQueryResult(dr, c.join.plan, ++qpCount, c.join.column._guid);