2011-04-07 87 views
2

我有三個DataTable需要連接在一起,並使用連接的數據作爲GridView的DataSource。第一個(localSQLTable)通過針對MS-SQL數據庫的查詢進行填充。後兩個(serviceResponse.Tables(0)serviceResponse.Tables(1))是使用DataSet.ReadXML從Web服務的結果構建的。LINQ to DataSet - 連接和GridView問題

我這個地步得到:

Dim joinedData = From f In localSQLTable _ 
       Join s1 As DataRow In serviceResponse.Tables(0) _ 
       On f.Item("KNum") Equals s1.Item("Number") _ 
       Join s2 As DataRow In serviceResponse.Tables(1) _ 
       On s1.Item("KNumber_Id") Equals s2.Item("KNumber_Id") _ 
       Select Guid = f.Item("Guid"), Num = f.Item("Num"), Desc = f.Item("Desc"), KNum = f.Item("KNum"), KDesc = s2.Item("KDescription_Text"), Type = s2.Item("Type") _ 
       Where (Type.ToString.ToUpper = "LONG_HTML") 

myGridView.DataSource = joinedData 
myGridView.DataBind() 

但是,它似乎joinedData只是一個IEnumerable(匿名類型)。我已經嘗試了一些東西,包括以下內容:

  • 使用lambda函數(我是其中不熟悉的話)來建立新的DataRow試圖建立joinedData作爲一個IEnumerable(中的DataRow)
  • 調用.ToList().AsEnumerable()的結果(與類型玩弄後)設置

的主要問題是,不管什麼我似乎嘗試,有一些錯誤使用結果作爲數據源爲我的GridView的 - 我兩個例外之一:

  • 帶ID的GridView的數據源沒有任何要從中生成列的屬性或屬性。確保您的數據源包含內容。
  • 數據源不支持服務器端數據分頁。

我也知道我可能不應該使用.Item ("Field"),而不是在我的Linq查詢的強類型.Field (Of T)("Field") - 我是在不改變等到我已經得到了數據的實際可用。

我沒有和Linq結婚;如果DataSet.Merge更合適(或其他一些方法),我會招待它。還有一種明顯的可能性,那就是我實際上不得不在晚些時候加入其他兩個DataTable。如果是這樣的話,我可能會將serviceResponse表合併爲一個,所以我仍然只能加入三張表。

那麼我能做些什麼來將這些數據結合在一起並將結果用作我的GridView的DataSource?而且我所做的任何事情都會比在我的原始DataTable(localSQLTable)中添加兩個額外列並使用XML響應數據逐行填充它們更快?

回答

0

這一切的最終結果是:

Dim joinedData As Generic.IEnumerable(Of DataRow) = (From f In localSQLTable.AsEnumerable() _ 
                Join h In serviceResponse.Tables(0).AsEnumerable() _ 
                On h.Item("serviceknum") Equals f.Item("knum") _ 
                Select GetFinalDataRow(finalTable, f, h)) 

gvGridOne.DataSource = joinedData.CopyToDataTable() 
gvGridOne.DataBind() 

我明確定義的數據表和模式(通過添加DataColumns)則結束數據表,我需要的,然後通過了DataTable,並在我的兩個數據行加入到GetFinalDataRow(),定義爲:

Public Function GetFinalDataRow(ByRef FinalTable As DataTable, ByVal Row1 As DataRow, ByVal Row2 As DataRow) As DataRow 
    Dim newRow As DataRow = FinalTable.NewRow() 
    For Each col As DataColumn In FinalTable.Columns 
     If Row1.Table.Columns.Contains(col.ColumnName) Then 
      newRow(col.ColumnName) = Row1.Item(col.ColumnName) 
     ElseIf Row2.Table.Columns.Contains(col.ColumnName) Then 
      newRow(col.ColumnName) = Row2.Item(col.ColumnName) 
     Else 
      newRow(col.ColumnName) = "" 
     End If 
    Next 

    Return newRow 
End Function 

我joinedData對象現在是一個IEnumerableØ f DataRows,我可以將它複製到我的GridView數據源的DataTable中,並且它會自動生成列並允許分頁。

2

在你選擇使用f.Field<Guid>("Guid")代替

例(C#)

gv.DataSource = serviceResponse.Tables[0].AsEnumerable().Select(r => new { Name = r.Field<Guid>("Guid") }); 
gv.DataBind(); 

例(VB)

gv.DataSource = dt.AsEnumerable().Select(Function(r) New With { .Name = r.Field(Of Guid)("Guid") }) 
gv.DataBind() 

或者在GridView上

編輯禁用AutoGenerateColumns 下面的查詢工作正常

void Main() 
{ 
    var dt1 = new DataTable(); 
    dt1.Columns.Add("Col1", typeof(string)); 

    var dt2 = new DataTable(); 
    dt2.Columns.Add("Col2", typeof(string)); 

    var row = dt1.NewRow(); 
    row[0] = "test"; 
    dt1.Rows.Add(row); 

    row = dt2.NewRow(); 
    row[0] = "test"; 
    dt2.Rows.Add(row); 

    var gv = new GridView(); 
    gv.DataSource = from t1 in dt1.AsEnumerable() 
        join t2 in dt2.AsEnumerable() 
         on t1[0] equals t2[0] 
        select new 
        { 
         Name1 = t1.Field<string>(0), 
         Name2 = t2.Field<string>(0) 
        }; 
    gv.DataBind(); 
} 
+0

對不起等待。我很樂意保持AutoGenerateColumns的真實性 - 我會盡快嘗試並回復您。 – 2011-04-08 20:26:54

+0

沒有工作 - 看起來像一個鑄造問題,就像我需要明確選擇數據行,也許。我收到以下內容: '無法將類型爲<<可怕的長字符串的對象稱爲匿名類型'來鍵入'System.Collections.Generic.IEnumerable'1 [System.Data.DataRow]'。' – 2011-04-11 15:23:49

+0

'在表上添加AsEnumerable()? – Magnus 2011-04-11 15:43:04