2017-01-18 88 views
0

我想獲得由LINQ查詢返回的項目的計數。我會認爲它是.Count但顯然不是。 我正在從Excel中加載DataTable,然後根據標識符獲取不同的行。我現在正在嘗試計算返回的項目數量。 Leases包含我希望計數的行的數據。我嘗試了一些東西(現在已經註釋掉了),但都沒有成功。如何獲得由LINQ查詢返回的項目的計數

也許一個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 
+0

嘗試使用此鏈接http:// stackoverflow。com/questions/3153641/linq-count-best-method –

+0

'租約'將成爲「內存查詢」 - 它不會有一個計數,直到你執行它。 ''LeaseCt =(Leases).Count()'會給你計數* that *查詢 – Plutonix

+0

'LeaseCt = Leases.ToList()。Count()' –

回答

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()。數據表擴展方法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擴展方法。

+0

謝謝,非常豐富 – GDutton

1

與ADO.NET和LINQ不玩新類型以及結構通常是類似清單(中(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已經從它NO'ToList()擴展,直到你「選擇」的東西。 DataTable與Linq恕我直言就像在高速公路上駕駛一輛錯誤的汽車一樣。因爲沒有什麼是很好的類型,並且作爲一個生產代碼的例子,我必須從WinForm解決方案中的'DataSet'中獲取某些內容,然後只需將一組特定的列列入POCO對象中,以製作我將擁有的列表做這樣的事情:

Dim ls = ds.Tables("tProduct").Select().Select(Function(x) New Product With {.ProductID = CInt(x("ProductId")?.ToString), .ProductDesc = x("ProductName")?.ToString}).ToList() 

有趣的東西。注意double select(),這不是拼寫錯誤。一個是System.Data.DataTable的擴展,另一個來自System.Linq.Enumerable。所以你需要選擇之前,你可以選擇哈哈。

+0

謝謝這是非常有用的! – GDutton