2014-01-07 2 views
1

Другой вопрос. Немного потрудившись с этим материалом SQL.Как слить два DataTables в DataSet в Jet SQL?

Я генерирую 2 таблицы из запросов в ADO.NET. Я хочу выполнить третий запрос из этих двух таблиц, которые не существуют в подключенной базе данных, но существуют в наборе данных. Я не могу для жизни понять, как это сделать. Я не хочу подключиться к базе данных, но к набору данных

Я посмотрел на попытки DataReaders, TableAdapters, DataTable.Select (который работает только для одной таблицы) и другие вещи. Ответ лежит в LINQ для наборов данных?

Благодаря Энди

Dim strSelect As String 
    Dim dsmcmd As OleDbDataAdapter   
    Dim dsm as New DataSet 

    strSelect = "TRANSFORM Sum(Items.amount) AS total SELECT Accounts.accCategory, Accounts.ID, Accounts.comment AS Account FROM Accounts INNER JOIN Items ON Accounts.ID = Items.accFrom WHERE (((Year([idate]))=2013) AND ((Items.category)<>3 Or (Items.category) Is Null) AND ((Accounts.accCategory)=6 OR (Accounts.accCategory)=7) AND ((Accounts.curr)=1)) GROUP BY Accounts.accCategory, Accounts.ID, Accounts.comment PIVOT Format(idate,'mmm') IN ('Jan','Feb','Mar','Apr', 'May','Jun','Jul','Aug','Sep','Oct','Nov','Dec')" 
    dsmcmd = New OleDbDataAdapter(strSelect, cn) 
    dsmcmd.Fill(dsm, "Spent") 

    strSelect = "TRANSFORM Sum(Items.amount) AS total SELECT Accounts.accCategory, Accounts.ID, Accounts.comment AS Account FROM Accounts INNER JOIN Items ON Accounts.ID = Items.accFrom WHERE (((Year([idate]))=2013) AND ((Items.category)=3) AND ((Accounts.accCategory)=6) AND ((Accounts.curr)=1)) GROUP BY Accounts.accCategory, Accounts.ID, Accounts.comment PIVOT Format(idate,'mmm') IN ('Jan','Feb','Mar','Apr', 'May','Jun','Jul','Aug','Sep','Oct','Nov','Dec')" 
    dsmcmd = New OleDbDataAdapter(strSelect, cn) 
    dsmcmd.Fill(dsm, "Allocated")   

    strSelect = "SELECT Totals.accCategory, Totals.ID, Totals.Account, Sum(Totals.Jan) AS Jan FROM (SELECT * FROM Allocated UNION SELECT * FROM Spent) AS Totals GROUP BY Totals.accCategory, Totals.ID, Totals.Account" 
    dsmcmd = New OleDbDataAdapter(strSelect, <** WHAT DO I PUT HERE **>) 
    dsmcmd.Fill(dsm, "Balance")   

ответ

0

Ответ, кажется, есть две части.

Если DataTables генерируются «в памяти», вы должны использовать LINQ

Dim t = (From totals In (allocated.AsEnumerable.Union(spent.AsEnumerable)) _ 
      Group totals By accCategory = totals.Item("accCategory"), ID = totals.Item("ID"), Account = totals.Item("Account") _ 
      Into g = Group _ 
      Select New With {Key .accCategory = accCategory, Key .ID = ID, Key .Account = Account, Key .Jan = g.Sum(Function(totals) If(IsDBNull(totals.Item("Jan")), 0, CDec(totals.Item("Jan"))))}).ToList 

Затем вы должны преобразовать его обратно в таблицу (если вы хотите, чтобы привязать его к DataGrid, например)

Public Function ToTable(Of T)(data As IList(Of T)) As DataTable 

    Dim properties As PropertyDescriptorCollection = TypeDescriptor.GetProperties(GetType(T)) 
    Dim table As New DataTable() 

    For Each prop As PropertyDescriptor In properties 
     table.Columns.Add(prop.Name, If(Nullable.GetUnderlyingType(prop.PropertyType), prop.PropertyType)) 
    Next 

    For Each item As T In data 
     Dim row As DataRow = table.NewRow() 
     For Each prop As PropertyDescriptor In properties 
      row(prop.Name) = If(prop.GetValue(item), DBNull.Value) 
     Next 
     table.Rows.Add(row) 
    Next 

    Return table 

End Function 

Единственная непонятная проблема - обработка Null (DBNull) - но я отправлю отдельный вопрос.

Andy

Смежные вопросы