2012-06-01 5 views
0

Мне сложно соединить 2 datatables и получить объединенный файл данных .Datatables left join linq

Первые данные (метки) содержат данные, включая принтер. Второй DataTable (принтеры) содержит ссылки принтера (ID> Unc)

Я хотел бы иметь в качестве endresult (присоединенной) а DataTable со всеми данными от первого DataTable с полем (Unc) второго DataTable.

Это то, что я пытался: (ум, что фиксированные дорожки для удобства ...)

Sub Main() 

    Dim ds1 As new DataSet 

    ds1.ReadXml("C:\Program Files (x86)\[COMPANY]\ASW2XML\BICOLOR_a07bfc62-501e-4444-9b6e-3b9d3550e1a4.xml") 

    Dim ds2 As New DataSet 

    Dim li As string() 

    li = IO.File.ReadAllLines("C:\Program Files (x86)\[COMPANY]\ASW2XML\printers.dat") 

    Dim printers As New DataTable("Printers") 

    printers.Columns.Add("REPRT2") 
    printers.Columns.Add("REPRT3") 

    For Each s In li.ToList 

     Dim dr As DataRow = printers.NewRow 

     dr.Item(0) = s.Split("=")(0) 
     dr.Item(1) = s.Split("=")(1) 

     printers.Rows.Add(dr) 

    Next 

    printers.AcceptChanges 

    Dim labels As DataTable = ds1.Tables(0) 

    Dim joined As new DataTable("data") 

     'Dim lnq = From label In labels.AsEnumerable Join printer In printers.AsEnumerable On label("REPRT") Equals printer("REPRT2") Select printer 
     'Dim lnq = From l In labels Group Join p In printers On l Equals p("REPRT2") Into Group From p In Group Select label = l, ppath = If(p Is Nothing, "(Nothing)", p("REPRT3")) 
     Dim lnq = labels.AsEnumerable().Where(Function(o)printers.Select("REPRT2 =" & o.Item("REPRT").ToString).Length = 0) 

     joined = lnq.CopyToDataTable 


End Sub 

Thx за вашу помощь и вдохновение!

grtz -S-

+0

Вы не должны жестко закодировать 'C: \ Program Files'. Есть люди, у которых нет дисков «C:». – SLaks

+0

Я скопировал свой код из сервисного проекта, чтобы получить легкий доступ к этому коду и жестко закодировал путь к 2 файлам, потому что в службе они динамичны. Мне нужен только «волшебный» ключ, а затем поставить этот запрос linq.copytodatable в мою службу. – grmbl

ответ

0

Я решил сделать это «жестким» способом и пропустить все строки в родительской таблице. Это идет очень быстро, в течение небольшого количества записей, я не знаю, работает это на большее количество записей скорость будет значительно уменьшаться по сравнению с использованием раствора Linq ...

Это код, который я м с использованием atm:

Sub Main() 

    Dim ds As new DataSet 

    ds.ReadXml("C:\Program Files (x86)\[COMPANY]\ASW2XML\BICOLOR_a07bfc62-501e-4444-9b6e-3b9d3550e1a4.xml") 

    Dim labels As DataTable = ds.Tables(0) 
    Dim printers As DataTable = GetPrinters 

    labels.Columns.Add("REPRT2").SetOrdinal(labels.Columns.IndexOf("REPRT")+1) 'insert new column after key column 
    labels.CaseSensitive=False 
    labels.AcceptChanges 

    For Each dr As DataRow In labels.Rows 

     Dim p As String = String.Empty 

     Try 
      p = printers.Select("ID='" & dr("REPRT") & "'")(0).Item("PATH").ToString 
     Catch ex As Exception 

     End Try 

     dr("REPRT2") = p 

    Next 

    labels.AcceptChanges 

End Sub 

Function GetPrinters As DataTable 

    Dim printers As New DataTable("Printers") 

    Dim li As string() 

    li = IO.File.ReadAllLines("C:\Program Files (x86)\[COMPANY]\ASW2XML\printers.dat") 

    printers.Columns.Add("ID") 
    printers.Columns.Add("PATH") 

    For Each s In li.ToList 

     Dim dr As DataRow = printers.NewRow 

     dr.Item(0) = s.Split("=")(0) 
     dr.Item(1) = s.Split("=")(1) 

     printers.Rows.Add(dr) 

    Next 

    printers.AcceptChanges 

    Return printers 

End Function 
1

Вы пробовали http://msdn.microsoft.com/en-us/library/system.linq.enumerable.join.aspx

Сделайте DataTables как расширение IEnumerable (например, список, как вы сделали) и присоединиться к LINQ бы сделать его легко работать.

затем отправьте объединенные таблицы в любой пункт назначения, который вы хотите.

+0

Можете ли вы привести пример, примененный в моем коде выше, пожалуйста? :) – grmbl

+0

@grmbl: Я перенес пример на сообщение. – Minus

1

Я думал, что комментарий будет сложнее понять, поэтому я переместил его в сообщение.

я написал немного strucure что Шоуда поможет вам понять, как присоединиться работы:

structure Label 
    Public printerId as long 
    Public driver as Strring 
end structure 

structure Printer 
    Public unc as string 
end structure 

Если установить метки и принтеры для DataTable (вместо указанных ниже структур), вам следует иметь что-то вроде:

function DoJoin() as datatable 
    'You might remove as datatable in query declaration 
    dim query as datatable = Labels.Join(Printers, Function(aLabel) aLabel, _ 
    function(aPrinter) aPrinter.unc, _ 
    function(aLabel, aPrinter) New With 
    { .printerID = aLabel.printerId, .driver = aLabel.Driver, _ 
     .unc = aPrinter.unc 
    }) 
    return query 
end function 

Однако я прославил это сегодня утром в блокноте, поэтому вам, возможно, придется это отрегулировать. Я просто хочу добавить, что вы должны иметь один и тот же тип контейнера для использования соединения (например: пример в Join at msdn они использовали 2 списка.), Которые совместимы с объектами Linq (данные, которые я не знаю).