Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Binding aus mehreren JOIN
Papst
myCSharp.de - Experte



Dabei seit:
Beiträge: 354
Herkunft: Kassel

beantworten | zitieren | melden

Mit was arbeitest du? Plain SQL mit ADO.NET (o.ä.)?

Prinzipiell gehst du so vor:

- Daten abfragen
- über die Daten iterieren & die Daten in ein Objekt Projezieren (1)
- die Daten an deine Darstellung anpassen (2)


in (1) erhälst du die Zeilen in einer Klasse wie


class MitarbeiterZuweisung 
{
  public int MitarbeiterId {get; set;}
  public string Name {get; set; }
  public string Baustelle {get ;set;}
  public int Tag {get; set; }
}

in (2) gehst du her und passt es so an, wie du es anzeigen willst. Du musst also die Zeilen nach MitarbeiterId gruppieren. Das geht am einfachsten via LINQ:


var groupedByEmployee = rows.GroupBy(r => r.MitarbeiterId);
Jetzt musst du die erhaltenen Daten nur noch in eine ObservableCollection<T> überführen, wobei T eine von dir erstellte Klasse ist, die dein View benötigt.
private Nachricht | Beiträge des Benutzers
T-Virus
myCSharp.de - Member



Dabei seit:
Beiträge: 1803
Herkunft: Nordhausen, Nörten-Hardenberg

beantworten | zitieren | melden

@TheQPat
Ich beziehe mich dabei auf die SQL Anweisung von Abt, die dir schon die Daten liefert für die Anzeige.
Mein Beispiel soll dir nur noch zeigen, wie du die Daten danach parsen musst.

Wenn du die Datenbankstruktur so wie schon gezeigt umbaust, dann hast du sowohl eine saubere Datenbank Struktur und kannst die Daten auch sauber anzeigen lassen.
Sollte alles kein Problem sein, wenn du dir die Zeit dafür nimmst und die Umsetzungen mal durchdenkst.
Den richtigen Code sowie die Datenstrukturen musst du natürlich umsetzen.
Wir geben dir nur Beispiele, die konkrete Umsetzung kannst dabei nur du machen.

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.
private Nachricht | Beiträge des Benutzers
TheQPat
myCSharp.de - Member



Dabei seit:
Beiträge: 19

Themenstarter:

beantworten | zitieren | melden

Die Datenbank Struktur ist bereit geändert. Steht ja oben wie sie jetzt ist.

Ich Arbeite mit einer Localen Datenbank aus Visual Studio.
CREATE TABLE [dbo].[TableBauvorhaben] (
    [BauvorhabenID] INT        IDENTITY (1, 1) NOT NULL,
    [Name]          NCHAR (20) NOT NULL,
    [Ort]           NCHAR (20) NOT NULL,
    [Abfahrt]       NCHAR (10) NOT NULL,
    PRIMARY KEY CLUSTERED ([BauvorhabenID] ASC)
);
CREATE TABLE [dbo].[TableMapping] (
    [Id]            INT IDENTITY (1, 1) NOT NULL,
    [MitarbeiterID] INT NULL,
    [BauvorhabenID] INT NULL,
    [DayID]         INT NULL,
    PRIMARY KEY CLUSTERED ([Id] ASC)
);
CREATE TABLE [dbo].[TablePersonal] (
    [Id]                INT          IDENTITY (1, 1) NOT NULL,
    [Vorname]           VARCHAR (16) NOT NULL,
    [Nachname]          VARCHAR (16) NOT NULL,
    [Vorarbeiter]       BIT          DEFAULT ((0)) NOT NULL,
    PRIMARY KEY CLUSTERED ([Id] ASC)
);


hab denn Code an meine Daten angepasst:


        public class MitarbeiterBaustellenRelation
        {
            public string Name { get; set; }

            public int Tag { get; set; }

            public string Bauvorhaben { get; set; }
        }

        // Verarbeitet die Liste der Relationen und liefert Dummy Mitarbeiter Objekte
        public List<Mitarbeiter> ParseMitarbeiterBaustellenRelationen(List<MitarbeiterBaustellenRelation> relationen)
        {
            Dictionary<string, Mitarbeiter> bekannteMitarbeiter = new Dictionary<string, Mitarbeiter>();

            foreach (var relation in relationen)
            {
                // Mitarbeiter über den Namen suchen
                if (!bekannteMitarbeiter.TryGetValue(relation.Name, out var mitarbeiter))
                {
                    mitarbeiter = new Mitarbeiter();
                    mitarbeiter.Name = relation.Name;
                    bekannteMitarbeiter[mitarbeiter.Name] = mitarbeiter;
                }

                switch (relation.Tag)
                {
                    case 1:
                        mitarbeiter.BaustelleMo = relation.Bauvorhaben;
                        break;

                    case 2:
                        mitarbeiter.BaustelleTue = relation.Bauvorhaben;
                        break;
                }
            }

            return new List<Mitarbeiter>(bekannteMitarbeiter.Values);
            
        }

konnte ich aber noch nicht teste.

Ich frage meine Daten ab und lege Sie ins DataGridView1.
string sSQL_TableCombine = "SELECT M.Id, M.Vorname, Map.DayID, B.Name FROM TablePersonal M INNER JOIN TableMapping Map ON Map.MitarbeiterId = M.Id INNER JOIN TableBauvorhaben B ON Map.BauvorhabenID = B.BauvorhabenID";
DataGridView1.ItemsSource = clsDB.Get_DataTable(sSQL_TableCombine).DefaultView;

Ich erinnere mich an meine alten Zeiten aus PHP, da war das nicht so umständlich.
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von TheQPat am .
private Nachricht | Beiträge des Benutzers
T-Virus
myCSharp.de - Member



Dabei seit:
Beiträge: 1803
Herkunft: Nordhausen, Nörten-Hardenberg

beantworten | zitieren | melden

Deine Mapping Tabelle macht so keinen Sinn.
In einer Mapping Tabelle bilden i.d.R. die PKs aus den jeweiligen Tabellen, die du mappen willst, den eigentlichen PK und damit auch den Eintrag selbst ab.

Du hast hier aber eine eigene ID Spalten als Identity angelegt, die hat in der Tabelle nichts zu suchen.
Eigentlich sollten hier nur die Spalten für den Mitarbeiter PK, Tag und Baustellen PK drin stehen.
Diese sollten auch nicht NULL sein, was dem Sinn der Mapping Tabelle wiedespricht.
Wenn es kein Mapping für einen Fall geben soll, dann gibt es in der Tabelle auch keinen Eintrag.

Auch macht deine Bezeichnung der Tabellen so keinen Sinn.
Du musst nicht nochmal als Prefix Table* angeben.
Hier wäre es sinnvoller die Tabellen direkt und knapp zu bezeichnen wie ebn Mitarbeiter, Baustellen etc.
Die Mapping Tabelle würde ich z.B. als MitarbeiterBaustellenMapping anlegen, da es auch andere Mappings in der Datenbank geben könnte.

Dein aktueller Ansatz geht auch wieder in die falsche Richtung.
Du sollst doch die Daten wie beim Beispeil von Abt auslesen und dann parsen.
Jetzt haust du einfach ein DataTable in dein Grid, was die Anzeige auch nicht wie von dir gewünscht haben kann.

Ich habe irgendwie Zweifel, dass du recht verstehst was du machen solltest obwohl es klar geschrieben steht.

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.
private Nachricht | Beiträge des Benutzers
TheQPat
myCSharp.de - Member



Dabei seit:
Beiträge: 19

Themenstarter:

beantworten | zitieren | melden

Zitat von T-Virus
Deine Mapping Tabelle macht so keinen Sinn.
In einer Mapping Tabelle bilden i.d.R. die PKs aus den jeweiligen Tabellen, die du mappen willst, den eigentlichen PK und damit auch den Eintrag selbst ab.

Oben hab ichs geschrieben dann heißt es es passt so, was denn jetzt?
Zitat von T-Virus
Du hast hier aber eine eigene ID Spalten als Identity angelegt, die hat in der Tabelle nichts zu suchen.
Eigentlich sollten hier nur die Spalten für den Mitarbeiter PK, Tag und Baustellen PK drin stehen.
Diese sollten auch nicht NULL sein, was dem Sinn der Mapping Tabelle wiedespricht.

Da hast du recht, ergibt keinen sinn, aber wenn ich die Tabelle nicht auslesse etc. stört sich auch nicht?
Zitat von T-Virus
Wenn es kein Mapping für einen Fall geben soll, dann gibt es in der Tabelle auch keinen Eintrag.


genau so ist es, und somit gibt es ja auch keinen NULL wert? Weill kein Eintrag in der Datenbank ist.




Zitat von T-Virus
Auch macht deine Bezeichnung der Tabellen so keinen Sinn.
Du musst nicht nochmal als Prefix Table* angeben.
Hier wäre es sinnvoller die Tabellen direkt und knapp zu bezeichnen wie ebn Mitarbeiter, Baustellen etc.
Die Mapping Tabelle würde ich z.B. als MitarbeiterBaustellenMapping anlegen, da es auch andere Mappings in der Datenbank geben könnte.

Dient zur übersichtlichkeit, zum Besseren Verständnis JA, ändert aber nichts am eigentlich Problem. Es ist ein bestehendes Programm das ich vor langer Zeit Progammiert hatte und auch lauffähig war. Dies soll nur erweitert werden.

Zitat von T-Virus
Dein aktueller Ansatz geht auch wieder in die falsche Richtung.
Du sollst doch die Daten wie beim Beispeil von Abt auslesen und dann parsen.
Jetzt haust du einfach ein DataTable in dein Grid, was die Anzeige auch nicht wie von dir gewünscht haben kann.

Jop, so einfach hatte ich es bisher.

Zitat von T-Virus
Ich habe irgendwie Zweifel, dass du recht verstehst was du machen solltest obwohl es klar geschrieben steht.

für jemanden der das Täglich macht, mag das zutreffen. Mein Problem ist von anfang an die Daten in das DataGrid zu bekommen.
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15618
Herkunft: BW

beantworten | zitieren | melden

Zitat von TheQPat
Oben hab ichs geschrieben dann heißt es es passt so
Also ich sehe kein Problem mit der Mapping Tabelle.
Das einzig verwirrende ist die "DayId", weil "Id" eigentlich eine andere Referenz meint; Du aber ja einfach die Ziffern 1-7 für den Wochentag.
Und die FKs dürfen halt eigentlich nicht NULLable sein.
Zitat von T-Virus
Du hast hier aber eine eigene ID Spalten als Identity angelegt, die hat in der Tabelle nichts zu suchen.
Eigentlich sollten hier nur die Spalten für den Mitarbeiter PK, Tag und Baustellen PK drin stehen.
Da hast Du einen Denkfehler, T-Virus.
Das würde stimmen, wenn ein Mitarbeiter zu einer Baustelle nur einen Tag haben kann - das ist hier aber nicht der Fall.
Da der Mitarbeiter zu einer Baustelle an mehreren Tagen sein kann, kannst Du nicht die FKs als IDs nehmen - Du brauchst also die extra Mapping Id.

Seine Umsetzung ist also korrekt.
Zitat von TheQPat
Mein Problem ist von anfang an die Daten in das DataGrid zu bekommen.
Ja, und das ist eben, weil Dir bisschen die Grundlagen fehlen. Du denkst auch glaube ich immer noch, dass man Daten direkt so anzeigen kann wie man sie speichert oder abfragt; und das ist halt leider nicht / aller aller meistens nicht der Fall. Man muss in 99% Query-Resultate aufarbeiten; vor allem Joins.
Grundlagen vermitteln ist in einem Forum aber sehr schwer; das ist nicht unbedingt das perfekte Medium.
Ein Forum kann sehr sehr gut bei konkreten Probleme helfen - aber wir können es Dir halt nicht abnehmen, dass Du die Grundlagen lernen musst.
private Nachricht | Beiträge des Benutzers
TheQPat
myCSharp.de - Member



Dabei seit:
Beiträge: 19

Themenstarter:

beantworten | zitieren | melden

Zitat von Abt
Das einzig verwirrende ist die "DayId", weil "Id" eigentlich eine andere Referenz meint; Du aber ja einfach die Ziffern 1-7 für den Wochentag.
Und die FKs dürfen halt eigentlich nicht NULLable sein.
also:
NULLable raus
Id raus
und DayId durch DayNumber ersetzen?


Zitat von Abt
Ja, und das ist eben, weil Dir bisschen die Grundlagen fehlen. Du denkst auch glaube ich immer noch, dass man Daten direkt so anzeigen kann wie man sie speichert oder abfragt; und das ist halt leider nicht / aller aller meistens nicht der Fall. Man muss in 99% Query-Resultate aufarbeiten; vor allem Joins.
Grundlagen vermitteln ist in einem Forum aber sehr schwer; das ist nicht unbedingt das perfekte Medium.
Ein Forum kann sehr sehr gut bei konkreten Probleme helfen - aber wir können es Dir halt nicht abnehmen, dass Du die Grundlagen lernen musst.


Ich glaube zu wissen wie man es macht, aber ich kann den code nicht zusammen stückeln.

Ich habe früher sachen mit WinForms erstellt, dort konnte man es direkt in ein Grid Packen.

Vom Prinzip her meint ihr glaub ich: Datenbank lesen -> Daten aufbereiten -> Daten ausgeben (wpf). Das Verwirrende ist aber die ganze Verknüpfung und verwürfele und da steige ich irgendwie aus.
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15618
Herkunft: BW

beantworten | zitieren | melden

Zitat von TheQPat
also:
NULLable raus
Id raus
und DayId durch DayNumber ersetzen?
Wie gesagt: Du brauchst die Id.
Siehe mein Beitrag.
Zitat von Abt
Ich glaube zu wissen wie man es macht, aber ich kann den code nicht zusammen stückeln.
Das glaube ich noch nicht so ganz :-)
Du versuchst ja immer noch den SQL Query direkt an das DataGrid als Source zu hängen. Das funktioniert aber nur in den aller, aller, aller simpelsten Fällen; hier nicht mehr.
Zitat von TheQPat
Ich habe früher sachen mit WinForms erstellt, dort konnte man es direkt in ein Grid Packen.
Nein, dieser Fall geht auch nicht mit Windows Forms.
Zitat von TheQPat
Vom Prinzip her meint ihr glaub ich: Datenbank lesen -> Daten aufbereiten -> Daten ausgeben (
Richtig. Du überspringst den zweiten Punkt; brauchst ihn aber in diesem Fall.
private Nachricht | Beiträge des Benutzers
TheQPat
myCSharp.de - Member



Dabei seit:
Beiträge: 19

Themenstarter:

beantworten | zitieren | melden

Zitat von Abt
Das glaube ich noch nicht so ganz :-)
Du versuchst ja immer noch den SQL Query direkt an das DataGrid als Source zu hängen. Das funktioniert aber nur in den aller, aller, aller simpelsten Fällen; hier nicht mehr.

Jop, das war der bestands code denn ich gepostet hatte.

Zitat von Abt
Richtig. Du überspringst den zweiten Punkt; brauchst ihn aber in diesem Fall.

Genau. Ich kann denn Punkt nicht umsetzen. Das ist mein Grundproblem das ich seit erstellen des Beitrags habe ...
private Nachricht | Beiträge des Benutzers
Th69
myCSharp.de - Experte

Avatar #avatar-2578.jpg


Dabei seit:
Beiträge: 3988

beantworten | zitieren | melden

Lies dir auch mal [Artikel] Drei-Schichten-Architektur durch.
Die Datenbankabfrage gehört in den DAL (Repository), während die Aufbereitung der Daten in die Logikschicht bzw. ins Viewmodel gehört.
private Nachricht | Beiträge des Benutzers