Dataset->Db und LINQ Problem mit WHERE

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 13 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Dataset->Db und LINQ Problem mit WHERE

    Ich nutze das Dataset->Db Helpersprojekt und versuche mich mit der Verwendung von LINQ. Es verhält sich anders als gedacht :(

    Mein Ziel ist, alle Datensätze aus der Tabelle Objekte in eine DataRow-Collection zu kopieren, deren Spalte Ordnung dem Wert von intOrdnung entspricht.
    Die DataRow-Collection drcstelle ich mir so vor, daß ich mit drc(0) eine DataRow habe. Das scheint auch so zu sein.


    VB.NET-Quellcode

    1. Dts.Objekte.CustomFill("")
    2. Dim intOrdnung = 0
    3. Dim drc = Dts.Objekte.Where(Function(x) x.Ordnung = intOrdnung)
    4. For z = 0 To drc.Count - 1
    5. '...
    6. Next


    drc enthält nach der Zuweisung Dim drc = Dts.Objekte.Where(Function(x) x.Ordnung = intOrdnung) eine DataRow.
    Sobald drc.Count erreicht wird, springt VB zu Function(x). Ich verstehe nicht weshalb. Danach geht es weiter nach x.Ordnung = intOrdnung und in den DataSetDesigner nach:

    VB.NET-Quellcode

    1. Public Property Ordnung() As Integer
    2. Get
    3. Try
    4. Return CType(Me(Me.tableObjekte.OrdnungColumn),Integer)
    5. Catch e As Global.System.InvalidCastException
    6. Throw New Global.System.Data.StrongTypingException("Der Wert für Spalte Ordnung in Tabelle Objekte ist DBNull.", e)
    7. End Try
    8. End Get
    9. Set
    10. Me(Me.tableObjekte.OrdnungColumn) = value
    11. End Set
    12. End Property


    Dort gibt es den Fehler Ungültige Konvertierung von Typ DBNull in Typ Integer., weil Der Wert für Spalte Ordnung in Tabelle Objekte ist DBNull."

    Ich verstehe erstens nicht, weshalb VB zurückspringt, und zweitens nicht, weshalb Ordnung plötzlich = DBNull sein soll.
    --------
    Lieber inkompetent als inkontinent

    100Volt schrieb:

    Ich verstehe erstens nicht, weshalb VB zurückspringt...
    Ja, das ist bei Linq und anonymen Methoden mitunter recht undurchsichtig. Die .Where()-Extension verschleiert ja eine interne Foreach-Schleife, die das was im Where() steht, immer wieder abruft

    100Volt schrieb:

    Dort gibt es den Fehler Ungültige Konvertierung von Typ DBNull in Typ Integer., weil Der Wert für Spalte Ordnung in Tabelle Objekte ist DBNull."
    Ich verstehe zweitens nicht, weshalb Ordnung plötzlich = DBNull sein soll.
    Warum denn nicht? Schau mal in die Datenbank, und vergewisser dich.

    Ansonsten vielleicht nochmal codeproject.com/Articles/10309…l-Datamodel-for-Beginners durcharbeiten, und Folge-Artikel.
    Ist ja nicht aus Daffke, dass da beim Thema Datenmodelllierungs-Richtlinien dringend davon abgeraten wird, DbNull überhaupt zuzulassen.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „ErfinderDesRades“ ()

    @VB1963:
    Prüfe in der WHERE-Klausel vorher noch auf IsNull:
    Not x.IsOrdnungNull AndAlso x.Ordnung = intOrdnung

    Nun soll ich x deklarieren. Was ist x denn für ein Datentyp?

    Und drc ist nun kein Sammlungstyp mehr.


    @EdR:
    Die .Where()-Extension verschleiert ja eine interne Foreach-Schleife, die das was im Where() steht, immer wieder abruft

    Die Info hatte ich so nirgendwo gefunden, erklärt aber einiges :)


    Schau mal in die Datenbank, und vergewisser dich.

    In der Datenbank/Tabelle gibt es nur einen Datensatz und bei dem Ist Ordnung = 0. Da habe ich natürlich zuerst nachgeguckt.



    Wenn Where im Grunde eine For-Each-Schleife ist, dann ist mein Code dafür nicht geeignet, oder? Ich erwarte in dem Code eine DataRowCollection, was meiner Vorstellung nach sowas wie ein DataRow-Array ist. Mit dieser Sammlung von DataRows möchte ich weiterarbeiten. Das geht aber offenbar so nicht.

    Wie mache ich es denn richtig?
    --------
    Lieber inkompetent als inkontinent

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „100Volt“ ()

    Ich kann mir das nicht erklären.
    Wenn CustomFill Daten aus der Datenbank holt, dann sind die Daten anschliessend im Dataset.
    Wenn in der Datenbank keine Daten mit Ordnung==DbNull sind, dann ist auch im Dataset kein Datensatz mit Ordnung==DbNull.
    Wenn diese Exception kommt, ist da aber einer.

    ?(

    Da kann man nur nochmal genau hingucken:

    VB.NET-Quellcode

    1. Dim objekte = Dts.Objekte.ToArray()
    Haltepunkt drauf und im Lokalfenster in dieses Array reingucken und die Datensätze untersuchen.
    Du hast recht, ich habe immer in der falschen Tabelle geguckt. Es gibt die Tabellen Objekte und ObjekteArt, beide haben eine Spalte Ordnung.
    Ursprünglich hatte ich Spalten mit gleichen Namen unterschiedlich benannt. Diese beiden hießen früher Ordnung_Objekte und Ordnung_ObjekteArt, so wie meine Primärschlüsselspalten immer ID_<tabellenname> hießen (nun überall nur noch ID). Das hatte ich gemacht, damit genau so etwas nicht passieren kann. Wie ärgerlich um die Stunden der Fehlersuche :(

    Vielen Dank für Eure Hilfe!!!

    -------------- NACHTRAG --------------


    Dim drc = Dts.Objekte.Where(Function(x) Not x.IsOrdnungNull AndAlso x.Ordnung = intOrdnung)

    Das wird angemeckert: IsOrdnungNull ist kein Member von dsMain.ObjekteRow



    --------
    Lieber inkompetent als inkontinent

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „100Volt“ ()

    hmm - war halt nicht richtig hingeguckt. Davor gibt es keinen Schutz. Auch eine monströse Benamung wird dich da nicht schützen.
    Der Unterschied zwischen Objekte.Ordnung und ObjekteArt.Ordnung muss ausreichen, um die beiden zu unterscheiden.
    Ich würd das keinesfalls umbenennen zu Objekte.Ordnung_Objekte und ObjekteArt.Ordnung_ObjekteArt.



    Aber wieder passt das nicht zusammen: Die Fehlermeldung sagt, Objekte.Ordnung sei DbNull. Daraus folgt, dass in den Eigenschaften der Spalte Objekte.Ordnung AllowNull=True besteht.
    Wenn das so ist, generiert der DatasetDesigner aber die Methode Objekte.IsOrdnungNull - und somit dürfte das Angemecker nicht auftreten.
    Aber du kannst auch mal die Klasse OrdnungRow im ObjectBrowser angucken, Screenshot machen, dann gucken wir mal an, was es da für Methoden gibt.

    Auch das: "Angucken der typisierten Klassen im ObjectBrowser" ist ausführlich behandelt in codeproject.com/Articles/10309…l-Datamodel-for-Beginners und Folge-Artikeln (Artikel 3, Abschnitt "Excursus 1: master the ObjectBrowser and its Usage" + "Explore the typed Dataset").
    Nee, ich benenne das auch nicht mehr alles nochmals um. Mit Fielmann wäre das nicht passiert... ;)

    Objekte.Ordnung durfte zu dem Zeitpunkt noch DbNull sein. Ist aber schon geändert.
    Das Gemeckere passierte nicht erst zur Laufzeit. x.IsOrdnungNull war mit einer roten Wellenlinie unterstrichen.

    Die Klasse OrdnungRow finde ich nicht. Du meinst ObjekteRow, oder? Darin gibt es einige Funktionen, die nach dem Schema Is<Spaltenname>Null benannt sind. Für Ordnung gibt es keine Funktion, was jetzt wohl auch richtig ist, da DbNull nicht mehr erlaubt ist. Dann brauche ich die Prüfung allerdings auch nicht :)
    --------
    Lieber inkompetent als inkontinent

    100Volt schrieb:

    Mit Fielmann wäre das nicht passiert...
    Was ist das :?:

    100Volt schrieb:

    Für Ordnung gibt es keine Funktion, was jetzt wohl auch richtig ist, da DbNull nicht mehr erlaubt ist. Dann brauche ich die Prüfung allerdings auch nicht
    Funktioniert der LINQ denn jetzt :?:
    drc enthält nach der Zuweisung Dim drc = Dts.Objekte.Where(Function(x) x.Ordnung = intOrdnung) eine DataRow.Sobald drc.Count erreicht wird, springt VB zu Function(x). Ich verstehe nicht weshalb.
    mit

    VB.NET-Quellcode

    1. Dim drc = Dts.Objekte.Where(Function(x) x.Ordnung = intOrdnung).ToList
    wird nicht mehr zurückgesprungen, weil die Auflistung fertig iteriert ist und eine List(of T) erstellt wurde...

    100Volt schrieb:

    Die Klasse OrdnungRow finde ich nicht.
    OMG - Fielmann!!!
    Dabei ich schwöre - grad vor drei Tagen war ich da!

    100Volt schrieb:

    Darin gibt es einige Funktionen, die nach dem Schema Is<Spaltenname>Null benannt sind. Für Ordnung gibt es keine Funktion, was jetzt wohl auch richtig ist, da DbNull nicht mehr erlaubt ist. Dann brauche ich die Prüfung allerdings auch nicht
    Super!
    Offsichtlich kommst du langsam auf Trichter.