Announcement

Collapse
No announcement yet.

LINQ to Dataset - Was mach' ich falsch?

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • LINQ to Dataset - Was mach' ich falsch?

    Hallo zusammen,

    ich habe folgende Query mittels LINQ in VB.net erstellt:

    Code:
    Dim DaSe As New System.Data.DataSet()
    Dim DaTa As DataTable
    
    Dim cmd As New System.Data.SqlClient.SqlCommand
    cmd.Connection = Con
    cmd.CommandText = "SELECT * FROM Personen"
    Dim Ada As System.Data.SqlClient.SqlDataAdapter = _ 
    New System.Data.SqlClient.SqlDataAdapter(cmd)
    Ada.Fill(DaSe)
    Con.Close()
    
    DaTa = DaSe.Tables("Tab1")
    
    Dim query = From T In DaTa.AsEnumerable _
    Where T.Field(Of Integer)("ID") = 1 _
    Select T.Field(Of String)("Nachname")
    
    DataGridView1.DataSource = query
    Leider erhalte ich kein Ergebnis!

    Meine Imports sind:

    Imports System.IO
    Imports System.Data
    Imports System.Linq
    Imports System.Data.Linq
    Imports System.Data.DataTableExtensions

    Wo liegt mein Fehler?

  • #2
    Hallo,

    auf den ersten Blick würde ich sagen dass ein ToList() fehlt.

    Warum?
    LINQ führt die Abfragen verzögert aus, d.h. die Daten werden erst geholt (korrekt: die Enumeration wird erst ausgeführt) wenn sie benötigt werden.

    Durch ein zB ToList() werden die Daten benötigt und die Abfrage ausgeführt.

    Somit: DataGridView1.DataSource = query.ToList() sollte das Problem beheben.


    Anmerkungen:
    • Warum verwendest du nicht den LINQ2SQL O/R-Mapper?
    • Coole Signatur Frage: Gibts beim Sex keinen Debugger?



    mfG Gü
    "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

    Comment


    • #3
      Hey gfoidl,

      danke für die schnelle Antwort. Leider erhalte ich inzwischen bei meiner query die Meldung:

      "Der Wert darf nicht NULL sein. Parametername: source"

      Das ToList() hat leider nix gebracht.

      Originally posted by gfoidl View Post
      Coole Signatur Frage: Gibts beim Sex keinen Debugger?
      Wer den erfindet, würde bestimmt ordentlich absahnen!

      Comment


      • #4
        "Der Wert darf nicht NULL sein. Parametername: source"
        Kann nur raten: Vermutlich bekommt die Query keine Daten.

        Geh mal mit dem Debugger durch und schau dir die Inhalte der Varialben an.


        mfG Gü
        "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

        Comment


        • #5
          Also die ursprüngliche Fehlermeldung hab' ich jetzt beseitigt.

          Leider liefert mir die query gar keine "ToList()" Methode. Und wenn ich es trotzdem mit ToList() mache erscheint folgende Meldung:

          "Der offentliche Member ToList für den Typ EnumerableRowCollection(Of String) wurde nicht gefunden."

          Ich erhalte aber auf jeden Fall ein Ergebnis auf meine Abfrage. Wenn ich dort einen Breakpoint setze enthält Sie das korrekte Ergebnis. Das Problem scheint wohl die Ausgabe ins DataGridView zu sein.
          Zuletzt editiert von Gooner85; 28.07.2009, 12:00.

          Comment


          • #6
            Code:
            var query = from row in dt.AsEnumerable()
            		where row.Field<int>(0) == 1
            		select row.Field<string>(1);
            
            dataGridView1.DataSource = query.ToList();
            Geht doch (ist zwar in C# aber äquivalent zu VB.net).


            Dennoch die Frage:
            Warum verwendest du nicht den LINQ2SQL O/R-Mapper?
            Und warum willst du in einem DataGridView einen einzelnen Wert (ist das Result der Query) darstellen? Dafür könnte eine TextBox verwendet werden.


            mfG Gü
            "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

            Comment


            • #7
              Es muss doch nicht sein dass das nur ein einzelnes Ergebnis bringt oder? Wenn mehrere Zeilen dem Ergebnis entsprechen kommen mehrere zurück oder?
              Unsere Jugend ist unerträglich, unverantwortlich und entsetzlich anzusehen! - Aristoteles

              Comment


              • #8
                Originally posted by das-d View Post
                Es muss doch nicht sein dass das nur ein einzelnes Ergebnis bringt oder? Wenn mehrere Zeilen dem Ergebnis entsprechen kommen mehrere zurück oder?
                Stimmt - hab den (falschen) Schluss gezogen da nach ID gefiltert wird.


                mfG Gü
                "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

                Comment


                • #9
                  Also wie gesagt, bei mir tut sich da nix.
                  Es muss sich nicht immer um nur eine Wert handeln, es können durchaus mehrere Datensätze aufgelistet werden.

                  Beim mir funktioniert das mit .ToList() zumindest nicht.

                  Ich werd's dann wohl mal mit dem LINQ2SQL O/R-Mapper probieren.
                  Obwohl ich schon gerne wissen würde, warum es bei mir nicht hinhaut.

                  Comment


                  • #10
                    Vielleicht liegt es gar nicht an Linq. Hast du denn Code mal richtig debugged?

                    Code:
                    DaTa = DaSe.Tables("Tab1")
                    Wie kommst du darauf das das Ergebnis in einer DataTable Namens "Tab1" landet? Ich vermute nach obigem Aufruf ist DaTa weiterhin NULL. Ich würde erstmal das Dataset rauswerfen(im gezeigten Code ist das eh überflüssig) und die DataTable direkt befüllen.

                    Danach solltest du dir überlegen ob du denn das ganze in ADO.NET oder in Linq2SQL löst. Die Mischung von beidem erscheint wenig sinnig.

                    Comment


                    • #11
                      Ich hab' das hier vergessen:

                      Code:
                      Ada.Fill(DaSe, "Tab1")
                      Damit ist klar, welche Table ich anspreche!

                      Mir scheint es auch sinnvoller zum ADO.NET Entity Framework überzugehen. Mit LINQ werd' ich wohl nicht glücklich werden.

                      Comment


                      • #12
                        Mir scheint es auch sinnvoller zum ADO.NET Entity Framework überzugehen. Mit LINQ werd' ich wohl nicht glücklich werden.
                        Das ist irgendwie ein Trugschluss. LINQ ist nur eine in die Programmiersprache integrierte Abfragesprache. LINQ kann somit auch im ADO.net Entity Framework verwendet werden bzw. wird dort verwendet.

                        Ich verwende für den DB-Zugriff LINQ2SQL und nicht das ADO.net EF da dieses für wirklich große (Datenbank-) Projekte gedacht ist. LINQ2SQL ist leichtgewichtiger und die Einarbeitungszeit wesentlich geringer als beim EF.
                        Das EF bietet dafür mehr Möglichkeiten - ob man diese braucht oder nicht weiß ich nicht (siehe Anmerkung).

                        Persönliche Anmerkung:
                        Wenn eine Datenbank gut entworfen ist dann ist es nicht unbedingt notwendig mit einem O/R-Mapper eine andere "Struktur" der Datenbank zu entwerfen wie die mit den meisten O/R-Mappern möglich ist. Außerdem setzt meist auf der Datenzugriffschicht (DAL) eine Logikschicht (BAL) auf welche die Daten ihrerseits sowieso wieder transferiert/projiziert/...
                        Insofern finde ich es schade dass Mircosoft die Weiterentwicklung von LINQ2SQL nicht mehr voll vorantreibt bzw. eingestellt hat.


                        mfG Gü
                        "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

                        Comment


                        • #13
                          Also ich hab' jetzt mit dem O/R-Mapper und LINQ to SQL gemacht. Jetzt funktioniert das wunderbar:

                          Code:
                                  Dim db As New DataClasses1DataContext
                          
                                  Dim query1 = From T In db.Personen _
                                  Where T.ID = 1 _
                                  Select T
                          
                                  DataGridView1.DataSource = query1
                          Eine Frage hab' ich nun aber doch noch: Gibt's eine ähnliche Möglichkeit auch für LINQ to Dataset?
                          So erhalte ich keine Ausgabe:

                          Code:
                                  Dim ds As New DataSet1
                          
                                  Dim query2 = From T In ds.Personen _
                                              Where T.ID = 1 _
                                              Select T
                          
                                  DataGridView2.DataSource = query2
                          Damit ich nicht eine dauerhafte Datenbankverbindung brauche, wäre das von Vorteil.
                          Zuletzt editiert von Gooner85; 28.07.2009, 15:24.

                          Comment


                          • #14
                            LINQ - DataContext

                            Damit ich nicht eine dauerhafte Datenbankverbindung brauche, wäre das von Vorteil.
                            Ich glaub du verstehst nicht ganz wie LINQ2SQL funktioniert.


                            Der DataContext stellt die Objekte dar welche die Datenbanktabellen mappen.
                            Wird eine Abfrage gegen den DataContext gesetzt wird die Abfrage verzögert ausgeführt (deferred execution) und sobald die Daten benötigt werden wird die Abfrage gegeben die Datenbank ausgeführt. Die Daten werden von der Datenbank geholt und im Object-Cache des DataContext gehalten. Auf diese Daten wird zugegriffen - die Verbindung zur Datenbank wird dabei wieder geschlossen (die erledigt der DataContext automatisch).

                            D.h. die Objekte die verwendet werden stammen aus dem Object-Cache und es ist keine dauerhafte Verbindung zur Datenbank notwendig.

                            Lediglich der DataContext bleibt für die Dauer der Operation - hier: die Datenbindung an das DGV - offen. Oder korrekter ausgedrückt: Eine Referenz auf den DataContext wird gehalten. Dieser ist aber "nur" ein Objekt.


                            Insofern verstehe ich dein Anliegen nicht oder nicht was du meinst.


                            mfG Gü
                            Zuletzt editiert von gfoidl; 28.07.2009, 15:34. Reason: Titel hinzugefügt
                            "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

                            Comment


                            • #15
                              Danke gfoidl, hast recht, ich hab' das anscheinend wirklich etwas falsch verstanden. Aber wenn der DataContext die Connection automatisch schließt soll mir das natürlich sehr recht sein.

                              Schön, damit hat sich dann die Sache mit dem Dataset erledigt.

                              Danke nochmal!

                              Comment

                              Working...
                              X