【发布时间】:2014-10-29 14:03:16
【问题描述】:
我有一个在 VB.Net 中构建数据表的函数
Public Function GetDataTableFromSqlDataReader(ByVal dr As SqlDataReader) As DataTable
Dim dtSchema As DataTable = dr.GetSchemaTable()
Dim dt As New DataTable
Dim listCols As New ArrayList
If Not dtSchema Is Nothing Then
For Each drow As DataRow In dtSchema.Rows
Dim columnName As String = System.Convert.ToString(drow("ColumnName"))
Dim column As New DataColumn(columnName, DirectCast(drow("DataType"), Type))
column.Unique = CBool(drow("IsUnique"))
column.AllowDBNull = CBool(drow("AllowDBNull"))
column.AutoIncrement = CBool(drow("IsAutoIncrement"))
listCols.Add(column)
dt.Columns.Add(column)
Next
End If
While dr.Read()
Dim dataRow As DataRow = dt.NewRow()
For i As Integer = 0 To listCols.Count - 1
dataRow(DirectCast(listCols(i), DataColumn)) = dr(i)
Next
dt.Rows.Add(dataRow)
End While
Return dt
End Function
我正在返回一组数据,其中包含列(用户名、TeamID、10/1/2014、10/2/2014、..... 10/29/2014)和大约 15 行数据。
当数据读取器构建数据表并添加列时,它们不是按照上面的顺序排列,而是 UserName、TeamID、10/14/2014、10/8/2014、10/20/2014.. ..没有明显的模式。
我已经验证了 SQL 数据集是正确的,并且在构建数据表时出现了问题。
关于为什么会发生这种情况的任何想法,或者我应该查看哪些其他内容?此代码在所有其他情况下都可以正常工作,但是这一次它没有按正确的顺序添加列。
编辑:
如果有什么不同,我正在使用的 SQL 将获取用户名、团队 ID、项目计数和日期,并将它们放入临时表中。我是他们旋转数据以获取姓名/团队ID列表以及单行中每天的计数。 #P 只是日期列表,#M 保存要返回的数据。
insert into #P(PV)
select DISTINCT ReportDate
FROM #M;
select @Pivot = coalesce(@Pivot+',','')+'['+PV+']'from #P;
SET @SQL = 'select * from (select UserName,TeamID,ReportDate,PropertyValue from #M) StdP PIVOT (SUM(PropertyValue) FOR ReportDate IN ('+@Pivot+')) as PVT order by TeamID, UserName'
EXEC(@SQL)
这是我的 SQL 查询返回的顺序:
这是 VB.Net 数据阅读器给我的顺序..
【问题讨论】:
-
为什么不直接使用DataTable.Load() ?
-
这不是我写的,是我替换的开发人员写的,它被用于我们拥有的每个应用程序中。直到这次事件,它工作得很好。人们并不热衷于改变已经建立的东西。否则,我想进行大量更改以使代码更高效。
-
不知道为什么顺序不一样,但你能试着把你的 foreach 改成这个吗?
for each drow in dtSchema.AsEnumerable().OrderBy(Function(x) x("ColumnOrdinal")) -
我非常喜欢@Steve 的建议,但您也可以在您的
Return dt声明之前重新排序数据表本身的列... 看起来肯定是个hack,但可能如果你问我,最安全的方法......stackoverflow.com/a/12937748/1693085 -
@Steve:尝试了你的建议,第一次约会仍然是 10/14。在这一点上,我正在考虑必须使用 hack 来解决它。 ://