[.NET 1.1] Aggregate filter op DataTable geeft problemen

Pagina: 1
Acties:

  • whoami
  • Registratie: December 2000
  • Laatst online: 00:54
Ik ben vandaag op volgend probleem gebotst:
Uit een DataTable wil ik de records selecteren die meer dan 1 gerelateerd record hebben in een gerelateerde datatable.

Om het even te verduidelijken, stel dit schema:
Afbeeldingslocatie: http://users.pandora.be/fgzone/blog/northwind_ds.JPG

Ik wil dus alle Categorieën selecteren, waarvoor er méér dan 1 product aan die categorie gelinked is.
Dit kan ik eenvoudig doen mbhv de Select method van de DataTable:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
Dataset1 ds = new Dataset1 ();
Dataset1.CategoriesRow c = ds.Categories.NewCategoriesRow ();
c.CategoryID = 1;
c.CategoryName = "Category 1";
ds.Categories.AddCategoriesRow (c);

Dataset1.CategoriesRow c2 = ds.Categories.NewCategoriesRow ();
c2.CategoryID = 2;
c2.CategoryName = "Category 2";
ds.Categories.AddCategoriesRow (c2);

Dataset1.ProductsRow p1 = ds.Products.NewProductsRow ();
p1.ProductID = 1;
p1.CategoryID = 1;
p1.ProductName = "Product 1";
ds.Products.AddProductsRow (p1);


Dataset1.ProductsRow p2 = ds.Products.NewProductsRow ();
p2.ProductID = 2;
p2.CategoryID = 1;
p2.ProductName = "Product 2";
ds.Products.AddProductsRow (p2);

ds.AcceptChanges ();

string filterExpression;

filterExpression = "COUNT (Child.CategoryID) > 1";

DataRow[] dr = ds.Categories.Select (filterExpression);

foreach( Dataset1.CategoriesRow ct in dr )
{
    Console.WriteLine (ct.CategoryName);
}

Dit doet gewoon wat het moet doen; in het output window verschijnt netjes 'Category 1'.
Echter, stel nu dat ik na de AcceptChanges call nog een product toevoeg. Dan zijn alle Categorieën en de 2 producten dus 'unmodified', en krijgt het nieuwe product de RowState Added:
code:
1
2
3
4
5
Dataset1.ProductsRow p3 = ds.Products.NewProductsRow ();
p3.ProductID = 3;
p3.CategoryID = 1;
p3.ProductName = "Product 3";
ds.Products.AddProductsRow (p3);

Als ik nu opnieuw diezelfde filter uitvoer, dan krijg ik een exceptie voor m'n kiezen. :(
An unhandled exception of type 'System.Data.VersionNotFoundException' occurred in system.data.dll

Addition information: There is no original data to access.
Dit is wel een beetje zuur natuurlijk, en vooral omdat het in .NET 2.0 wel goed blijkt te werken. Een bug in .NET 1.1 dus, en ik kan niet zomaar naar 2.0 overstappen. :(

Dus de vraag: weet er iemand hoe ik hier, op een efficiente wijze rond kan werken ? Ik kan natuurlijk de volledige Categories DataTable gaan overlopen, en voor iedere category gaan kijken hoeveel producten eraan gerelateerd zijn zoals :
code:
1
2
3
4
5
foreach( Dataset1.CategoryRow c in ds.Categories )
{
   if( c.GetProducts().Length > 1 )
   ....
}
maar dit is nu eenmaal niet echt efficient te noemen ...

Iemand een beter idee ? Of iemand die weet hoe deze bug kan gefixed worden ?

https://fgheysels.github.io/


  • whoami
  • Registratie: December 2000
  • Laatst online: 00:54
Hmm, misschien wordt het wel opgelost met deze fix van MS, maar deze is helaas niet publiek beschikbaar . :(

https://fgheysels.github.io/


  • Vedett.
  • Registratie: November 2005
  • Laatst online: 08:28
Waarom werk je niet met een DataRelation?

code:
1
2
3
DataRelation rel = new DataRelation(),
rel.ParentColumns;
relChildColumns;


Nog nooit problemen mee gehad, en ik veronderstel dat ik zo'n situatie al wel heb meegemaakt.

  • whoami
  • Registratie: December 2000
  • Laatst online: 00:54
Hoe kan ik daarmee, op een efficiente manier, de categorieën ophalen die meer dan één gerelateerd product hebben ?
Ik toon in m'n startpost dat ik het idd kan oplossen door gebruik te maken van de DataRelation, maar da's helemaal niet efficient, omdat ik dan over alle categorieën moet loopen. Voor een klein aantal records is dat nog wel te doen, maar als het over 20.000 rows gaat, is dat wel een beetje veel.

Tenzij jij natuurlijk nog iets anders bedoelt.

https://fgheysels.github.io/


  • Vedett.
  • Registratie: November 2005
  • Laatst online: 08:28
Sorry, niet aandachtig genoeg gelezen. En nu nog zie ik het woord DataRelation niet staan. Maar 20.000! Volgens mij moet je geen DataSet gebruiken, maar een DataBase.

Ik heb het niet zo voor DataSets. Zeker niet wanneer je er logica uit wilt gaan halen zoals je nu doet
( "Count(<kolomnaam>) > 0" ). Dit blijft natuurlijk persoonlijk.

  • whoami
  • Registratie: December 2000
  • Laatst online: 00:54
Ik ben ook niet zo voor DataSets, en ja , ik gebruik een Database. Echter, die applicatie haalt gegevens mbhv remoting uit de DB, en die ik een boomstructuur moet wergeven. Dan is het gewoon beter om alles wat ik nodig heb in één keer uit de DB te halen, ipv met een lazy load iedere keer gegevens uit de DB te trekken als dat nodig is. Die remote calls zijn nl .ook duur.
En ja, dat gaat snel. :) (Het zijn dan wel veel records, maar niet veel zo veel gegevens).

De user kan dan die boomstructuur aanpassen, en ja, die logica heb ik nodig om achteraf een paar checks te doen.

ik weet heus wel waar ik mee bezig ben ...

(En het woord 'DataRelation' staat er niet, maar in het laatste code-voorbeeldje kan je wel zien dat er een DataRelation gebruikt wordt).

https://fgheysels.github.io/

Pagina: 1