Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[.net] join van datatables

Pagina: 1
Acties:
  • 222 views sinds 30-01-2008
  • Reageer

  • hing
  • Registratie: Augustus 2002
  • Laatst online: 19-05-2023
Een "probleempje" dat denk ik wel interresant is voor de bezoekers van dit forum:

Ik laad xml en een xsd document in een dataset.
Deze is mooi gevuld en de relaties tussen de datatables binnen die dataset is goed aangegeven.
Een stukje uit de XML (vereenvoudigd):
XML:
1
2
3
4
5
6
7
8
9
10
11
12
<data attr1="x" attr2="y">
  <item>1</item>
  <item>2</item>
  <item>3</item>
  <item>4</item>
</data>
<data attr1="a" attr2="b">
  <item>5</item>
  <item>6</item>
  <item>7</item>
  <item>8/item>
</data>


.net is zelf zo slim om hier 2 tabellen van te maken:
"data" en "item" waarbij .net zelf ook id's genereert om de tabellen goed aan elkaar te koppelen.
Nu wil ik de tabellen joinen. Dat doe ik als volgt:
Visual Basic:
1
2
3
4
5
6
7
dim ds as dataset
dim dt as datatable

ds.ReadXmlSchema(...)
ds.ReadXml(...)
dt = ds.tables("data")
dt.Merge(ds.Tables("item"), False, MissingSchemaAction.AddWithKey)


Het resultaat van deze merge is echter slechts 2 records:
(ongeveer)
Visual Basic:
1
2
3
data_id     attr1    attr2    item
0           x        y        4
1           a        b        8


Ik krijg dus slechts 2 records, terwijl ik graag 8 gezien zou hebben.
Voer ik de join op de juiste manier uit? Of moet dit anders?
Ik heb nog geprobeerd om data en item om te draaien maar dat levert een foutmelding op.
Iemand enig idee in welke richting ik een oplossing kan vinden?

De oplossingen die ik op internet heb gezien zijn meestal niet echt netjes. Men lost dit meestal op door door de twee tabellen te loopen en zelf op die manier een 3e tabel te genereren.

Mij lijkt dat dit gewoon via de dataset/datatables kan aangezien er relaties tussen de tabellen zijn en .net ook alle tabellen op de juiste manier aan elkaar koppelt door zelf keys/id's/kolommen te genereren waarop gekoppeld kan worden.

[ Voor 13% gewijzigd door hing op 18-01-2008 12:43 ]


  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

Huh, heb je gelezen wat Merge doet? Merge zal je data tabel uitbereiden met de extra velden uit 'item', maar zal tekens data a.b en data x.y updaten met de informatie uit items. Dus a.b krijgt eerst item waarde 1, dan een update naar 2, 3 en als laatste 4.

Merge is eigenlijk een combinatie van insert en update. Vergelijkbaar met de MySQL replace functie. Merge uit SQL2008 kan dit ook, maar is flexibeler. Merge doet een insert als een record nog niet aanwezig en anders een update.

DataSets hebben geen expliciete join optie. Wel kun je de 'data' tabel doorlopen en van een 'data' record GetChildRows() aanroepen. Die geeft dan de 4 gekoppelde 'item' records terug.

Via LINQ kun je wel simpel meerdere collecties samenvoegen tot 1 resultaat
C#:
1
2
3
4
5
6
var joinQuery = from d in Data //uitgaand van typed dataset
     join i in Items on d.data_id=i.data_id
     select new { DataId = d.data_id, Attr1 = d.attr1, Attr2 =  d.attr2, Item = i.item };

foreach(var item in joinQuery)   //  <-- hier worden de tables pas samengevoegd
   Console.WriteLine("Item {0}.{1} has value '{2}'", item.Attr1, item.Attr2, item.Item);


Dat levert een IEnumarable collectie met een 'anonymous' type met de properties DataId, Attr1, Attr2 en Item.

If it isn't broken, fix it until it is..


  • hing
  • Registratie: Augustus 2002
  • Laatst online: 19-05-2023
zelf door de rows en childrows itereren, daar heb ik al aan gedacht als last resort oplossing. Lijkt me niet echt fraai en foutgevoelig (zeker als de XML verandert).

Microsoft heeft zelf een class vrijgegeven (JoinView) die dit kan.
Ik vind het overigens wel raar dat je alle mogelijkheden biedt om relaties, restricties etc op de datatables in een dataset kunt loslaten, maar niet normaal de data eruit kunt plukken.

Ik zal dat LINQ eens bekijken. Thanks!

[ Voor 4% gewijzigd door hing op 18-01-2008 16:25 ]


  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

Je kunt de dataset als XML document wegschrijven en via XsltCompiledTransform de gewenste structuur opbouwen en vervolgens opnieuw inlezen in een Dataset.

De relaties zijn aanwezig om GetChildRows() of GetParentRow() aan te kunnen roepen. De dataset is nooit bedoeld om als embedded database te fungeren. Hiervoor heeft Microsoft Sql Server Compact Edition beschikbaar (SqlClientCe) waarmee je middels SqlCommandCe gewoon een 'normale' join query kunt uitvoeren.

Zelf maken wij al langer gebruik van LINQ omdat data management toch een stuk eenvoudiger wordt.

If it isn't broken, fix it until it is..


  • hing
  • Registratie: Augustus 2002
  • Laatst online: 19-05-2023
Niemand_Anders schreef op vrijdag 18 januari 2008 @ 17:03:
De relaties zijn aanwezig om GetChildRows() of GetParentRow() aan te kunnen roepen. De dataset is nooit bedoeld om als embedded database te fungeren. Hiervoor heeft Microsoft Sql Server Compact Edition beschikbaar (SqlClientCe) waarmee je middels SqlCommandCe gewoon een 'normale' join query kunt uitvoeren.
Betekent dit dat je dan SQL Server CE "misbruikt" om queries uit te kunnen voeren op XML? Want in principe doe ik niets met databases...

Weet je verder hoe je LINQ kunt aanzetten in VS2005 (VB)?
Overal kom ik tegen hoe je LINQ queries moet maken, da's duidelijk, maar hoe je het kunt enablen is niet echt duidelijk.
In een videotutorial van MS wordt gezegt dat je je project moet porten naar VS2008, maar kom op het net genoeg voorbeelden tegen van VS2005. Ook zijn er een hoop boeken over LINQ in VS2005, dus dat suggereert dat LINQ wel degelijk is toe te passen in VS2005.

Tot nu toe heb ik framework 3.5 geinstalleerd, een reference naar LINQ en System.Core toegevoegd en de volgende code:
Visual Basic:
1
Imports System.Data.Linq


Heb ergens gelezen op een forum van microsoft dat framework 3.5 niet beschikbaar is voor VS2005. Dus hoe Linq te gebruiken in VS2005?

[ Voor 42% gewijzigd door hing op 21-01-2008 09:21 ]