Archief - [PROG][VB.NET] DataRow Cast Exception Error

Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.

dieterm

Legacy Member
Hallo allemaal.

Voor mijn eindwerk moet ik een programma schrijven in vb.net dat data uit een sqldatabase haalt en deze offline opslaat als xml.

Ik heb al enkele dagen zitten zoeken, maar vindt geen oplossing voor onderstaand probleem.

Ik zou graag het volgende doen, maar er treed steeds een exception op:
Code:
Private Sub GetVestigingTest()
        Dim myDataset As New DataSet("Hazop")

        'laad de data van een xml bestand
        myDataset.ReadXml("C:\XmlDatabase\Hazop.xml")

        Dim myDataRow As DataRow = myDataset.Tables("Vestiging").Rows(0)
        'hieronder gebeurt de exception
        Dim myVestiging As Vestiging = myDataRow

        MsgBox(myVestiging.Naam)
    End Sub

    Class Vestiging
        Inherits Data.DataRow

        Public Sub New(ByVal builder As DataRowBuilder)
            MyBase.New(builder)
        End Sub

        Property Naam() As String
            Get
                Return Item("naam")
            End Get
            Set(ByVal value As String)
                Item("naam") = value
            End Set
        End Property
    End Class

Dit is de exception die optreedt:
System.InvalidCastException was unhandled
Message="Unable to cast object of type 'System.Data.DataRow' to type 'Vestiging'."

Wie kan mij helpen om dit probleem op te lossen?

Alvast bedankt

Albireo

Legacy Member
Als je met Visual Basic.NET werkt is het waarschijnlijk het gemakkelijkst om een typed dataset te laten genereren. Dan krijg je automatisch een DataSet, DataTables en DataRows met de juiste properties en types.

Of je kan een conversion operator definiëren in je Vestiging class om een DataRow te converteren naar een Vestiging.

zoiets dan (in C#):
Code:
class Vestiging {
        private DataRow row;
        public Vestiging (DataRow row) {
            this.row = row;
        }
        public string Naam {
            get {
                return (string)this.row["Naam"];
            }
        }
        public static explicit operator Vestiging (DataRow row) {
            return new Vestiging(row);
        }
}
Vestiging erft nu wel niet meer van DataRow maar daar zag ik eerlijk gezegd geen reden voor (en het bleek nogal moeilijk te zijn om te implementeren ;)).

dieterm

Legacy Member
Hallo Albireo,

jouw oplossing is inderdaad ook een mogelijkheid, maar dan gaat er voor elke datarow, die ik als een Vestiging wil gebruiken, een Vestiging Object worden aangemaakt.

Stel dat ik dan 200 vestingingen wil hebben dan wil dat zeggen dat er 200 datarow-objecten en 200 vestinging-objecten gaan aangemaakt worden in het geheugen, of ben ik verkeerd?

En dan bestaat ook de kans dat als ik een Vestiging-object heb , waarvan ik de datarow manueel verwijder in de dataset, dan blijft het Vestiging-object nog steeds in het geheugen (en verwijst 'row' naar een datarow die niet meer bestaat)

Albireo

Legacy Member
Die datarow-objecten bestaan al in de dataset, er wordt gewoon een nieuwe referentie naar gemaakt in mijn Vestiging-object, dus geen 200 nieuwe datarows in het geheugen. Maar wel 200 nieuwe Vestiging-objecten die je niet zou hebben als Vestiging zou erven van DataRow... (IMHO)

[edit] Nieuwe poging die rekening houdt met deletes vanuit de dataset en die snel uit het geheugen verdwijnen. Op deze manier heb je bij een delete nog wel een datarow in de dataset (in de RowState "DataRowState.Deleted") maar geen corresponderend Vestigings-object meer.

Code:
    class Vestiging:IDisposable {
        private DataRow row;
        private bool disposed;
        public Vestiging(DataRow row) {
            this.row = row;
            this.row.Table.RowDeleting += new DataRowChangeEventHandler(Table_RowDeleting);
            this.row.Table.TableClearing += new DataTableClearEventHandler(Table_TableClearing);
        }
        void Table_RowDeleting(object sender, DataRowChangeEventArgs e) {
            if (e.Row == this.row) {
                this.row == null;
                this.Dispose(true);
            }
        }
        void Table_TableClearing(object sender, DataTableClearEventArgs e) {
            this.row == null;
            this.Dispose(true);
        }
        public string Name {
            get {
                if (this.disposed) {
                    throw new ObjectDisposedException("Vestiging");
                }
                return (string)this.row["Name"];
            }
            set {
                if (this.disposed) {
                    throw new ObjectDisposedException("Vestiging");
                }
                this.row["Name"]=value;
            }
        }
        public static explicit operator Vestiging(DataRow row) {
            return new Vestiging(row);
        }

        #region IDisposable Members

        public void Dispose() {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        #endregion

        protected virtual void Dispose(bool disposing) {
            disposed = true;
        }
        ~Vestiging() {
            Dispose(false);
        }
    }

Is een typed DataSet geen optie?

dieterm

Legacy Member
Hallo Albireo,

Kan je wat meer uitleg geven over wat een 'typed dataset' juist is?

Groeten,

Dieter

dieterm

Legacy Member
Blijkbaar werkte ik al met een typed dataset maar wist ik het zelf nog niet :)

Dit is inderdaad ook iets interessants dat ik zeker ga onderzoeken.

Alvast bedankt voor de tip!
Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.
Terug
Bovenaan