[C#] Collection Databinding issue Collection in Collection

Pagina: 1
Acties:

  • pjonk
  • Registratie: November 2000
  • Laatst online: 29-12-2025
Ik heb de volgende situatie:
Ik heb een Dao layer waarin Business objecten worden opgeslagen o.a. ook artikelen. Een artikel heeft standaard de volgende velden:
- Number (artikelnummer)
- Name (artikelomschrijving)

Nu is het zo dat sommige artikelen extra eigenschappen bevatten, bijvoorbeeld gewicht en kleur. Omdat deze eigenschappen variabel zijn worden deze in een aparte collectie opgeslagen.
Uiteindelijk ziet een Article object er als volgt uit:
C#:
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
public class Article
{
    private string _Number;
    private string _Name;
    private NameValueCollection _ExtraFields;
    
    public Article()
    {
        _ExtraFields = new NameValueCollection();
        
        // Fill some sample data for testing
        _ExtraFields.Add("Gewicht", "100 kg");
        _ExtraFields.Add("Kleur", "groen");
    }

    public NameValueCollection ExtraFields
    {
        get { return _ExtraFields; }
    }
    
    public String Number
    {
        get { return _Number; }
        set { _Number = value; }
    }   

    public String Name
    {
        get { return _Name; }
        set { _Name = value; }
    }
}

Nu heb ik een testje in ASP.NET gemaakt om deze artikelinformatie in een grid weer te geven.
code:
1
2
3
4
5
6
<asp:DataGrid id=DataGrid1 runat="server" autogeneratecolumns="false">
    <columns>
        <asp:BoundColumn HeaderText="Artikelnummer" DataField="Number" />
        <asp:Boundcolumn Headertext="Naam" datafield="Name" />
    </columns>
</asp:DataGrid>

De kolommen gewicht en kleur zijn dynamisch dus deze zal ik at run-time moeten toevoegen:
C#:
1
2
3
4
5
6
7
8
9
10
ArticleCollection items = catalog.Articles.SelectAll();

// Add column for weight
BoundColumn col = new BoundColumn();
col.HeaderText = "Gewicht";
col.DataField = "ExtraFields[\"Gewicht\"]";

DataGrid1.Columns.Add(col);
DataGrid1.DataSource = items;
DataGrid1.DataBind();

Het toevegen van de kolommen is geen probleem, maar ik moet ook vertellen uit welk veld hij de data moet halen. ExtraFields[\"Gewicht\"] gaat natuurlijk niet werken maar dit is wel wat ik wil. Hoe vertel ik de DataGrid dat hij bij het DataBinden het veld Gewicht uit de subcollectie ExtraFields moet halen?

It’s nice to be important but it’s more important to be nice


  • __fred__
  • Registratie: November 2001
  • Laatst online: 13:06
Waarschijnlijk gebruik je een O/R mapper of een andere code generation tool.
Je zit dus met het (vrij fundamentele) probleem dat een artikel bepaalde eigenschappen niet altijd heeft. Dat heeft sowieso problemen op een Datagrid, want dat is een tabular view van je data, en dat betekent dat je dus een lijst op je scherm wilt toveren waarvan bepaalde artikelen bijvoorbeeld geen kleur hebben, en wat toon je dan?

Mocht je een beetje gestructureerde groepen van eigenschappen dan kun je denken aan inheritance. Bijv. GedimensioneerdArtikel stamt af van Artikel en heeft wel een lengte c.q. breedte. Nadeel is dat .NET geen multiple inheritance ondersteunt dus dat je O/R mapper dat niet voor je kan genereren (als ie uberhaupt al een beetje verstand heeft van inheritance)
Niets houdt je natuurlijk tegen om nu zelf een property te bouwen in een al dan niet derived class die de goede waarde retourneert, zodat je de goede waarde krijgt.
De meeste O/R mappers bieden ook de mogelijkheid om views te maken en die te mappen naar een collectionset, zodat je op die manier netjes een datagrid kunt vullen, misschien is dat ook een optie.

  • pjonk
  • Registratie: November 2000
  • Laatst online: 29-12-2025
Bedankt voor je reactie. Ik gebruik een eigen OR/Mapper :) overigens wel gebaseerd op de architectuur van een bestaande OpenSource OR Mapper. Maar het probleem dat je schetst is precies waar ik mee zit: de artikeleigenschappen zijn te variabel. Dit is ook precies de reden dat ik deze eigenschappen niet in de basis entiteit zelf heb ondergebracht.

Een extra class met de extra eigenschappen die derived van Article is een optie, maar ik heb ook nog te maken met databases van verschillende klanten waarbij de artikelinformatie verschilt. Dit betekent dat ik per klant eigen derived article classes moet genereren.

Overigens heb ik wel een oplossing gevonden om tijdens het DataBinden die extra informatie dynamisch in de kolom te plaatsen via het ItemDataBound event:
C#:
1
2
3
4
5
6
7
8
9
private void DataGrid1_ItemDataBound(object sender, DataGridItemEventArgs e)
{
    if((e.Item.ItemType==ListItemType.Item ) || (e.Item.ItemType==ListItemType.AlternatingItem))
    {
        Article article = (Article)e.Item.DataItem;
        e.Item.Cells[2].Text = article.ExtraFields["Gewicht"];
        e.Item.Cells[3].Text = article.ExtraFields["Kleur"];
    }
}


Een eigen DataView maken is ook een optie, maar hierbij moet ik eerst mijn collection converteren naar een DataTable, vervolgens aan die DataTable mijn extra artikel informatie kolommen toevoegen, en daarna kan ik pas gaan Databinden. Performance-technisch gezien ook geen goed idee.

It’s nice to be important but it’s more important to be nice


  • Varienaja
  • Registratie: Februari 2001
  • Laatst online: 14-06-2025

Varienaja

Wie dit leest is gek.

pjonk schreef op maandag 20 februari 2006 @ 19:51:
Nu is het zo dat sommige artikelen extra eigenschappen bevatten, bijvoorbeeld gewicht en kleur. Omdat deze eigenschappen variabel zijn worden deze in een aparte collectie opgeslagen.
Als je artikelen zulke verschillende objecten zijn, dan is het misschien een idee om ze in verschillende klassen uit te splitsen, maar met een gemeenschappelijk hoofd-object. (Artikel, met als onderliggende klassen: krantenartiken, wetsartikel, enzovoort).

Wat je ook kunt doen, is gewoon alle artikelen alle velden geven. En dan de waarde null laten voor de artikelen waar de waarde niet van toepassing is.

Siditamentis astuentis pactum.