Laden...

Filterabfrage System.NullReferenceException

Erstellt von tristar vor einem Jahr Letzter Beitrag vor einem Jahr 303 Views
T
tristar Themenstarter:in
98 Beiträge seit 2016
vor einem Jahr
Filterabfrage System.NullReferenceException

Hallo,

ich rufe Daten aus der DB ab und binde diese an eine DataGridView. Klappt alles wunderbar.


public IEnumerable<Ansprechpartner> AlleAnsprechpartner()
        {
            using (IDbConnection db = new MySqlConnection(AppConnection.ConnectionString))
            {
                string q = @"SELECT
                            a.ID AS AnsprechpartnerId,
                            a.Abteilung AS Abteilung,
                            a.Email AS Email,
                            a.FaxNr AS FaxNr,
                            a.AdressId AS AdresseNr,
                            a.Nachname AS Nachname,
                            a.Vorname AS Vorname,
                            a.Titel AS Titel,
                            s.Firma AS Kunde
                            FROM tblansprechpartner a
                            LEFT JOIN tblstandort s ON a.AdressId = s.AdressId";

                return db.Query<Ansprechpartner>(q, commandType: CommandType.Text);
            }
        }

...
           var ansprechp = ansprechRepository.AlleAnsprechpartner().ToList();
            SortableBindingList<Ansprechpartner> sort = new SortableBindingList<Ansprechpartner>(ansprechp);
            dgUebersicht.DataSource = sort;


Nun möchte ich mit einer Textbox die Daten filtern:


var filteredList = ansprechRepository.AlleAnsprechpartner().Where(c => c.Nachname.ToString().Contains(textBox1.Text)).ToList();

Beim Filtern erhalte ich jedoch den Fehler:> Fehlermeldung:

System.NullReferenceException: "Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt."

Warum? Was ist falsch?
Kann es sein, weil ich als Tabelleneinträge bei Nachname auch null Werte habe?
Falls ja, wie kann ich das Problem lösen?

Ich habe es schon mit einer anderen Abfrage versucht, jedoch erhalte ich den selben Fehler:


string q = @"SELECT
                            a.AnsprechpID AS AnsprechpartnerId,
                            a.Abteilung AS Abteilung,
                            a.Frau_Herr AS Anrede,
                            a.Email AS Email,
                            a.FaxNr AS FaxNr,
                            a.StandortId AS StandortId,
                            a.Nachname AS Nachname,
                            a.Vorname AS Vorname,
                            a.Titel AS Titel,
                            s.Firma_Standort AS Kunde
                            FROM tblansprechpartner a
                            LEFT JOIN tblstandort s ON a.StandortID = s.StandortID
                            WHERE (a.Nachname IS NULL OR a.Nachname = @Nachname)";

T
2.216 Beiträge seit 2008
vor einem Jahr

Wenn du keine Where Klausel hast und es Einträge mit NULL als Nachname gibt, dann bekommst du diese auch.
Deine Where Klausel unten schließt diese auch noch explizit ein.

Entweder du musst die Null Einträge direkt per SQL filtern oder in deinem Filter bei Linq explizit auf null Filtern.
Per SQL wäre der bessere Weg, dann müssen überflüssige Daten nicht erst transportiert und materialisiert werden!

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

T
tristar Themenstarter:in
98 Beiträge seit 2016
vor einem Jahr

Entschuldige, aber irgendwie stehe ich auf dem Schlauch.
Habe die Abfrage nun wie folgt angepasst:


string q = @"SELECT
                            a.AnsprechpID AS AnsprechpartnerId,
                            a.Abteilung AS Abteilung,
                            a.Frau_Herr AS Anrede,
                            a.Email AS Email,
                            a.FaxNr AS FaxNr,
                            a.StandortId AS StandortId,
                            a.Nachname AS Nachname,
                            a.Vorname AS Vorname,
                            a.Titel AS Titel,
                            s.Firma_Standort AS Kunde
                            FROM tblansprechpartner a
                            LEFT JOIN tblstandort s ON a.StandortID = s.StandortID
                            WHERE (a.Nachname IS NOT NULL AND a.Nachname = @Nachname)";

Trotzdem erhalte ich weiterhin die Fehlermeldung??

T
2.216 Beiträge seit 2008
vor einem Jahr

Hast du deinen Code mal debuggt?
Mit der Where auf a.Nachname = @Nachname ist Null schon ausgeschlossen, wenn du auch einen Parameter mit einem Wert mitgibst.
Deine "IS NOT NULL" Einschränkung ist dadurch auch überflüssig.

Entsprechend bleibt nur noch der Verdacht, dass dein Code nicht korrekt ist oder du ein Objekt mit Null als Nachname hast.
Kann beides duch den debugger geprüft werden, kann ich von hier aber nicht für dich übernehmen 😉

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

T
tristar Themenstarter:in
98 Beiträge seit 2016
vor einem Jahr

Entsprechend bleibt nur noch der Verdacht, dass dein Code nicht korrekt ist oder du ein Objekt mit Null als Nachname hast.

Ich habe Objekte, die Null als Nachnamen haben. Nur verstehe ich leider nicht, wie ich das nun lösen kann??

T
2.216 Beiträge seit 2008
vor einem Jahr

Eine Lösung wäre Daten in der DB zu prüfen und zu korrigieren, falls Nachnamen immer vorhanden sein sollten.
Oder falls NULL in der DB erlaubt sein sollte, dann musst du deinen Filter im Lamba Ausdruck anpassen.
Einfach in dem du einen Null Check einbaust mit c.Nachname != null.

Vielleicht solltest du dich nochmal mit den Grundlagen beschäftigen, wenn es schon an solchen banalen Dingen scheitert.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

T
tristar Themenstarter:in
98 Beiträge seit 2016
vor einem Jahr

Hier mein Versuch den Filter anzupassen. Zwar ohne Fehlermeldung, aber leider werden auch keine Ergebnisse angezeigt.


var filter = ansprechpartnerRepository.AlleAnsprechpartner().Where(c => c.Nachname != null).Select(c => c.Nachname.ToString().ToUpper().Contains(textBox1.Text.ToUpper())).ToList();

Ist mein Filterausdruck falsch?
ODer kann es daran liegen, dass andere Einträge im Datensatz null sind?

16.774 Beiträge seit 2008
vor einem Jahr

Der Null-Check ist korrekt. Zum Rest können wir nichts sagen.
Debuggen und Gültigkeit überprüfen musst selbst. Wir haben weder Deine Anwendung noch Deine Daten vor uns.

Aber geh doch einfach strukturiert vor....?
Wenn Du denkst, dass was am Query nicht stimmt, dann beginn von vorn, füg dem Query nach und nach das Zeug zu: dann siehst Du, wenn etwas plötzlich keine Werte mehr liefert.

Hinweis: Du kannst mit Dapper nicht programmieren, wie mit EF Core. EF Core nimmt einem sehr viel ab, Dapper nicht.
Aber Du kannst auch hier den Repository Pattern anwenden, wie in EFCore auch und Dich danach orientieren. Dann macht man seltener Strukturfehler (siehe unten).

Allgemein, was ich sonst sehe:

  • Du hast List<>, Deine Methode liefert aber IEnumerable<> - unnötiger Runtime Impact und auch aus Software Design nich das gelbe vom Ei (SustainableCode/csharp/list-vs-ienumerable-enumerate at main · BenjaminAbt/SustainableCode)
  • ToUpper, um Case Sensitivity zu beachten, ist der falsche Weg: das sollte man über das DB Collate tun -> latin1_general_ci_as
  • Man eröffnet keine Connections in Methoden, sondern auf Context Ebene. In Methoden öffnen ist a) aus Software-Sicht kein guter Weg (Dependency) aber auch b) aus Runtime-sich das ineffizienteste, was man tun kann.
  • Der Typo bei Adress ist Absicht? Oder hat das ne Auswirkung auf Deine Resultate?
  • Das c.Nachname.ToString() ist mir rätselhaft. Ist doch ein String, wozu noch ToString() ?
  • Warum kennt der DAL auch UI Elemente: Contains(textBox1.Text.ToUpper())).ToList(); => [Artikel] Drei-Schichten-Architektur 🙂

Generelle Frage: Wenn Du Ansprechpartner mit gewissen Nachnamen willst, wieso lädst Du alle Ansprechpartner in den Speicher und Filterst auf dem Client?
Das ja super ineffizient. Mach doch einfach eine entsprechende SQL Abfrage, wie Datenbanken gedacht sind...?