我没有非常广泛地使用LINQ,但我正在尝试从大型Excel电子表格(14K行)读取数据,这需要我从多个工作表中进行查询,甚至重新查询原始电子表格以过滤特定数据 . 因为Excel的OleDb查询可能需要相对较长的时间(本地计算机上的文件每个查询500毫秒),我在我的方法前面做了几个这样的查询,通过“基础”DataTable开始循环然后尝试使用LINQ过滤掉该循环中的数据,以将适当的数据放入更结构化的DataSet中 . 这里有一些代码可以帮助解释(VB.NET):
Dim Connection As System.Data.OleDb.OleDbConnection
Dim Command As System.Data.OleDb.OleDbDataAdapter
Dim EXCEL_SHEET_DATA_1 As New DataTable
Dim EXCEL_SHEET_DATA_2 As New DataTable
Dim EXCEL_SHEET_DATA_3 As New DataTable
Dim TapeFile As New FileInfo("C:\TempFolder\tapefile.xls")
Connection = New System.Data.OleDb.OleDbConnection("provider=Microsoft.Jet.OLEDB.4.0; Data Source='" & TapeFile.FullName & "'; Extended Properties=Excel 8.0;")
Command = New System.Data.OleDb.OleDbDataAdapter("SELECT * FROM [SHEET1$] ORDER BY [USER_ID] ASC, [MEMBER_NUMBER] ASC;", Connection)
Command.Fill(EXCEL_SHEET_DATA_1)
Command.Dispose()
Command = New System.Data.OleDb.OleDbDataAdapter("SELECT * FROM [SHEET2$] ORDER BY [USER_ID] ASC, [MEMBER_NUMBER] ASC;", Connection)
Command.Fill(EXCEL_SHEET_DATA_2)
Command.Dispose()
Command = New System.Data.OleDb.OleDbDataAdapter("SELECT * FROM [SHEET3$] ORDER BY [USER_ID] ASC, [MEMBER_NUMBER] ASC;", Connection)
Command.Fill(EXCEL_SHEET_DATA_3)
Command.Dispose()
For Each Row As DataRow In EXCEL_SHEET_DATA_1.Rows
Dim MemberNumber As String = Row("MEMBER_NUMBER").ToString.Trim
Dim UserNumber As String = Row("USER_ID").ToString.Trim
' -- CODE FOR INITIAL PROCESSING OF SHEET1 DATA - NO ERRORS --
Dim CoMemberQuery As IEnumerable(Of DataRow) = From cm In EXCEL_SHEET_DATA_2 Where cm("MEMBER_NUMBER") = MemberNumber And cm("USER_ID") = UserNumber
For Each CoMemberRow As DataRow In CoMemberQuery
' -- CODE FOR PROCESSING OF SHEET2 DATA - NO ERRORS --
Next CoMemberRow
Dim VehicleQuery As IEnumerable(Of DataRow) = From veh In EXCEL_SHEET_DATA_1 Where veh("MEMBER_NUMBER") = MemberNumber And veh("USER_ID") = UserNumber Order By veh("VIN") Ascending
' *******************************************************
' -->> HERE IS WHERE I *SOMETIMES* GET THE EXCEPTION <<--
' *******************************************************
For Each VehicleRow As DataRow In VehicleQuery
' -- CODE FOR SECONDARY PROCESSING OF SHEET1 DATA - NO ERRORS --
Next VehicleRow
Next Row
我注意到可能与它有关的是,对于导致第一个异常的特定 MemberNumber
和 UserNumber
组合,结果集中的第一行很可能包含VIN字段的NULL值 .
我确定问题与我的LINQ查询语法有关,但我在这方面太缺乏经验,无法知道它为什么会失败 . 任何帮助将不胜感激 . 如果您需要有关代码或实现的任何其他信息,请告诉我,我会尝试将其添加到问题中 . 感谢您的时间 .
1 回答
您的VehicleQuery具有以下短语:
Order By veh("VIN") Ascending
.因此,只要
VehicleQuery
得到评估(通过启动For
循环),LINQ将评估该查询中的所有项目,然后执行排序操作,包括将veh("VIN")
值相互比较并按顺序排列 .在比较查询中的任何两个项时,它会尝试查看其中任何一个值是否知道如何将自身与另一个类型的值进行比较(因此实现了
IComparable
接口 . 如果它们不能,那么它不知道哪个应该先行 .我的猜测是
veh("VIN")
(有时)会产生不再使用的对象,以及你希望如何比较它们,你可能会考虑进行某种转换或转换,或者只是在值上调用ToString()
,以确保它具有可比性:Order By veh("VIN").ToString() Ascending
(请原谅任何语法错误,因为我是C#开发人员 . )