我有一个dataTable "date"它有字符串格式的日期。我不能用LINQ排序。
表例子
ID date
1 20.02.2022
2 15.05.2021
3 03.07.2019
这是我到目前为止的LINQ表达式,但它总是说String未被识别为有效的日期时间
(From x In dt.AsEnumerable()
Order By Convert.ToDateTime(x("date").ToString)
Select x).CopyToDataTable
我也试过这个,但结果相同
(From x In dt.AsEnumerable()
Order By DateTime.ParseExact(x("date").ToString,"dd/MM/yyyy",System.Globalization.CultureInfo.InvariantCulture)
Select x).CopyToDataTable
我错过了什么?
让你的生活更轻松;使用强类型数据表。它仍然可以像普通的数据表一样使用,但是使用
就不那么麻烦了。- 为您的项目添加一个新的数据集类型文件
- 将其命名为myprojectnamerataset
- 右键单击设计界面,选择Add DataTable,给它起一个好听的名字,比如Concerts
- 右键单击DataTable并添加列
- 将其命名为ID,将其设为int
- 添加另一列,命名为比日期更有趣的东西-也许是ConcertDate。避免将列命名为关键字或类型
- 设置为DateTime类型
这个可视化设计器实际上只是给你写了一个带有两个属性的类,int Id和DateTime ConcertDate,并且它使一个数据表能够保存它们。
当您将数据加载到表中时,然后进行解析(您必须现在它是强类型的)。这样做比每次查询
时都这样做更有效。Dim dt = new ConcertsDataTable()
'in a loop? Some api call? Wherever the data comes from
dt.AddConcertsRow(theId, DateTime.ParseExact(theDate, "dd.MM.yyyy", CultureInfo.InvariantCulture)
现在你可以更好地LINQ了;不需要AsEnumerabke,或者通过字符串挖掘列名并强制转换它们等
dt.OrderBy(Function(r) r.ConcertDate)
好:
Dim totalAttendancePast = 0
For Each ro in dt
If ro.ConcertDate < DateTime.Now Then totalAttendancePast += ro.Attendance
Next ro
令人厌恶:For Each ro as DataRow in dt.Rows
If DateTime.ParseExact(ro("ConcertDate"), "dd.MM.yyyy") < DateTime.Now Then totalAttendancePast += DirectCast(ro("Attendance"), Integer)
Next ro
更好:
dt.
Where(Function(r) r.ConcertDate < DateTime.Now).
Sum(Function(r) r.Attendance)
糟糕:
dt.AsEnumerable().
Where(Function(r) DateTime.ParseExact(ro("ConcertDate"), "dd.MM.yyyy") < DateTime.Now).
Sum(Function(r) r.Field(Of Integer)(Attendance))
你可以在任何你想使用普通数据表的地方使用这个强类型数据表——如果你迫切需要的话,你仍然可以通过字符串列名等方式访问它:
someDatagridview.DataSource = dt
someDataAdapter.Fill(dt)
MessageBox.Show(dt.Rows(0)("Id").ToString())
但是让智能感知能够引导你并留在强类型领域是非常有用的:
MessageBox.Show(dt.First().Id.ToString())
正如评论中指出的那样,我使用的是"dd/MM/yyyy"当我的数据是"20.02.2021"时。我使用了"dd.MM.yyyy">