如何计算LINQ查询返回的项目

时间:2017-01-18 17:26:43

标签: vb.net linq

我正在尝试获取LINQ查询返回的项目的计数。我认为它是.Count但显然不是。 我从Excel加载DataTable然后根据标识符获取不同的行。我现在正在尝试计算返回的项目。 Leases包含我想要计数的行的数据。我尝试了一些事情(现已注释掉),但都没有成功。

也许LINQ专家可以帮助我?

这是我的代码:

Dim Leases As Object
Dim dtData As System.Data.DataTable = LoadExcelAsDb(oFile.FullName)
Try
    ' How many leases are there
    Leases = From row In dtData.AsEnumerable() Select row.Field(Of Object)("F2") Distinct
    '    LeaseCt = New System.Linq.SystemCore_EnumerableDebugView(Of Object)(Leases).Items.count 
    '    LeaseCt = New System.Linq.Enumerable(Of Object)(Leases).Items.count
    '    LeaseCt = Leases.Count
Catch ex As Exception
    Debug.WriteLine("Error reading files" + ex.ToString)
End Try

''' <summary>
''' Loads an excel file as a datatable
''' </summary>
''' <param name="sFilename">Filename of excel to be loaded </param>   
''' <returns>Populated Datatable</returns>
Private Function LoadExcelAsDb(sFilename As String) As System.Data.DataTable
    ' Connect to Excel get table
    Dim oConnection As System.Data.OleDb.OleDbConnection = New System.Data.OleDb.OleDbConnection("provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + sFilename + " ; Extended Properties=Excel 12.0;")
    Dim oCommand As System.Data.OleDb.OleDbDataAdapter = New System.Data.OleDb.OleDbDataAdapter("select * from [Sheet1$]", oConnection)

    Dim DtSet As System.Data.DataTable = New System.Data.DataTable
    Try
        oCommand.Fill(DtSet)
    Catch ex As Exception
        Debug.WriteLine("Error reading files" + ex.ToString)
    End Try

    Return DtSet
End Function

2 个答案:

答案 0 :(得分:1)

通常,使用ADO.NET和Linq的DataTable对于通常类似于List(Of(PocoObject))的较新类型的结构不能很好地发挥作用。然而,通常你可以通过以下方式欺骗它:

Sub Main()
   Dim dt As DataTable = New DataTable()
   dt.Columns.Add(New DataColumn("Id", GetType(Integer)))
   Dim row As DataRow = dt.NewRow()
   row("Id") = 1
   dt.Rows.Add(row)
   Dim row2 As DataRow = dt.NewRow()
   row2("Id") = 2
   dt.Rows.Add(row2)

   'Shows 2 rows
    Console.WriteLine(dt.Select().ToList().Count)

    Console.ReadLine()
End Sub

密钥是DataTable没有&#39; ToList()&#39;延期,直到你选择&#39;它的东西。与Linq恕我直言的DataTable就像在高速公路上以错误的方式驾驶汽车。因为没有什么是好的类型,并且作为一些生产代码的例子,我必须从“数据集”中获得一些东西。我有一个WinForm解决方案然后只是将一组特定的列输出到POCO对象来制作列表我必须做这样的事情:

Dim ls = ds.Tables("tProduct").Select().Select(Function(x) New Product With {.ProductID = CInt(x("ProductId")?.ToString), .ProductDesc = x("ProductName")?.ToString}).ToList()
有趣的东西。注意双精选(),这不是拼写错误。一个是System.Data.DataTable的扩展,一个来自System.Linq.Enumerable。所以你需要选择才能选择lol。

答案 1 :(得分:1)

使用LINQ时需要掌握的一个主要概念是被查询的对象必须是可枚举的。这意味着它至少实现了接口System.Collections.IEnumerable。优选地,查询的对象将实现System.Collections.Generic.IEnumerable(Of T)接口。

在LINQ语句中

Leases = From row In dtData.AsEnumerable() Select row.Field(Of Object)("F2") Distinct

查询的对象是结果dtData.AsEnumerable()。 Datatable扩展方法AsEnumerable返回System.Data.EnnumerableRowCollection(Of System.Data.DataRow),因此语句中的row变量的类型为DataRow

语句选择 row.Field(Of Object)("F2")。由于这将返回System.Object类型的单个对象,因此查询结果将为System.Collections.Generic.IEnumerable(Of Object)类型。但是,您要将结果分配给以这种方式定义的变量Leases

Dim Leases As Object

对于以这种方式声明的变量,你无能为力。如果您将其声明为查询返回的类型会更好。

Dim Leases As System.Collections.Generic.IEnumerable(Of Object)

以这种方式定义,Leases可以通过System.Linq.Enumerable类中声明的方法进行扩展,以允许调用Count扩展方法。