myCSharp.de - DIE C# und .NET Community
Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 
 | Suche | FAQ

» Hauptmenü
myCSharp.de
» Startseite
» Forum
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Suche
» Regeln
» Wie poste ich richtig?
» Forum-FAQ

Mitglieder
» Liste / Suche
» Wer ist wo online?

Ressourcen
» openbook: Visual C#
» openbook: OO
» Microsoft Docs

Team
» Kontakt
» Übersicht
» Wir über uns

» myCSharp.de Diskussionsforum
Du befindest Dich hier: Community-Index » Diskussionsforum » Entwicklung » GUI: WPF und XAML » Entity Framework CORE und WPF Datagrid
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | Thema zu Favoriten hinzufügen

Antwort erstellen
Zum Ende der Seite springen  

Entity Framework CORE und WPF Datagrid

 
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
MGernot MGernot ist männlich
myCSharp.de-Mitglied

Dabei seit: 22.02.2009
Beiträge: 8


MGernot ist offline

Entity Framework CORE und WPF Datagrid

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo Leute,
ich bin blutiger Anfänger im Bereich EF Core und WPF und versuche derzeit mir diese Technologien selbst beizubringen.
Also ich habe in SQL Server zwei Tabellen erstellt (ChemischeAnalysen und ChemischeAnalysenDetails) und beide mit einem Fremschlüssel verknüpft. Anschließend habe ich in VS in einem Konsolen-Projekt das Model mit Scaffold-DBContext erstellt. Dann konnte ich einfach mit LINQ die Daten abfragen:

C#-Code:
var context = new Models.BetriebsdatenContext();
            var analysen = context.ChemischeAnalysen
                                                .Include(s => s.ChemischeAnalysenDetails)
                                                .ToList();

Das klappt einwandfrei und es kommen auch die korrekten Daten zurückgeliefert. Wobei ich jedoch gnadenlos gescheitert bin ist die Bindung der Daten der untergeordneten Tabelle an ein WPF Datagrid.
Ich kann die Daten der übergeordneten Tabelle ChemischenAnalysen problemlos binden, aber bei der den Chemischen Analysen untergeordneten Liste (ChemischeAnalysenDetails) wird in den Spalten nichts angezeigt und ich bekomme einen Binding Path expression Error für diese Felder.
(Siehe bitte Bild im Anhang.)
Irgendwo fehlt mir hier offensichtlich ein grundsätzliches Verständnis wie diese Bindung gehandhabt wird.Wenn mir hier bitte jemand einen Stubs in die richtige Richtung geben könnte, wäre ich sehr dankbar.Ich habe mir schon einiges zum Thema "WPF Databinding with nested Lists" angesehen, und verstehe einfach nicht warum es bei mir nicht funktioniert.

XML-Code:
<Window x:Class="WpfTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfTest"
        mc:Ignorable="d"
        Title="Analysis" Height="450" Width="800" Background="#FF797373"
>

    <Grid>
        <DataGrid x:Name="dataGrid1" HorizontalAlignment="Left" Height="401" Margin="10,10,0,0" VerticalAlignment="Top" Width="668" AutoGenerateColumns="False">

            <DataGrid.Columns>
                <DataGridTextColumn Header="Datum" Binding="{Binding Datum}" Width="100"/>
                <DataGridTextColumn Header="Bezeichnung" Binding="{Binding Bezeichung}" Width="100"/>
                <DataGridTextColumn Header="Anmerkung" Binding="{Binding Anmerkung}" Width="100"/>
                <DataGridTextColumn Header="Gerät" Binding="{Binding Gerät}" Width="100"/>
                <DataGridTextColumn Header="Kategorie" Binding="{Binding Kategorie}" Width="100"/>
                <DataGridTextColumn Header="Element" Binding="{Binding ChemischeAnalysenDetails.Element}" Width="50"/>
                <DataGridTextColumn Header="Wert" Binding="{Binding ChemischeAnalysenDetails.Wert}" Width="50"/>
                <DataGridTextColumn Header="ChemieID" Binding="{Binding ChemischeAnalysenDetails.ChemieId}" Width="*"/>
            </DataGrid.Columns>
        </DataGrid>
        <Button x:Name="btnPopulate" Content="Bind&#xD;&#xA;" HorizontalAlignment="Left" Height="27" Margin="683,10,0,0" VerticalAlignment="Top" Width="100" Click="BtnPopulate_Click"/>

    </Grid>
</Window>

Vielen herzlichen Dank für Eure Hilfe.

MGernot hat dieses Bild (verkleinerte Version) angehängt:
Grid.png
Volle Bildgröße

Neuer Beitrag 28.09.2019 18:12 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
MrSparkle MrSparkle ist männlich
myCSharp.de-Team

avatar-2159.gif


Dabei seit: 16.05.2006
Beiträge: 5.507
Herkunft: Leipzig


MrSparkle ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Wenn ChemischeAnalysenDetails eine Liste ist, dann gibt es dort keine Eigenschaft Element.

Wenn ich es richtig verstehe, hat jeder Datensatz eine Liste von ChemischeAnalysenDetails, und du versuchst, diese in der gleichen Tabelle darzustellen. Wie soll denn das Ergebnis aussehen, das du erwartest?
Neuer Beitrag 28.09.2019 18:52 Beiträge des Benutzers | zu Buddylist hinzufügen
witte
myCSharp.de-Mitglied

Dabei seit: 03.09.2010
Beiträge: 920


witte ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Schau dir mal das MVVM-Pattern an, damit kann man das relativ einfach lösen. Die grundlegende Idee wäre ein MainViewModel zu erstellen welches an die View gebunden wird. Dann benötigt man im ViewModel
* ein IEnumerable<ChemischeAnalyse> "List" für die die Hauptliste (gebunden an DataGrids ItemsSource)
* ein ChemischeAnalyse-Property "Current" das das aktuell im DataGrid gewählte Objekt repräsentiert (gebunden an DataGrids SelectedItem)
* ein IEnumerable<ChemischeAnalyseDetail> "Details" welches an das DetailGrid gebunden wird (ItemsSource)
Dann kann man prima im Setter von Current die Detailliste umhängen: wird ein anderes Objekt gewählt ändert sich Current, dann reicht einfach ein Details = Current.Details;
* ICommand's für Laden, Speichern etc
PS: Klassen sollten im Singular benannt werden um sie von namespaces unterschieden zu können.
Neuer Beitrag 28.09.2019 18:58 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
MGernot MGernot ist männlich
myCSharp.de-Mitglied

Dabei seit: 22.02.2009
Beiträge: 8

Themenstarter Thema begonnen von MGernot

MGernot ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo Mr. Sparkle,
danke für die Antwort.
Ja,das Ergebnis soll so sein wie in dieser Sicht in SQL Server.

Code:
1:
2:
3:
4:
5:
6:
7:
CREATE VIEW [dbo].[ChemischeAnalyse]
AS
SELECT dbo.ChemischeAnalysen.Datum, dbo.ChemischeAnalysen.Bezeichung, dbo.ChemischeAnalysen.Anmerkung, dbo.ChemischeAnalysen.Gerät, dbo.ChemischeAnalysen.Kategorie, dbo.ChemischeAnalysen_Details.Element, dbo.ChemischeAnalysen_Details.Wert, 
             dbo.ChemischeAnalysen_Details.ChemieID
FROM   dbo.ChemischeAnalysen LEFT OUTER JOIN
             dbo.ChemischeAnalysen_Details ON dbo.ChemischeAnalysen.headerId = dbo.ChemischeAnalysen_Details.ChemieID
GO

Die beiden Klassen die EF Core generiert hat schauen so aus:

C#-Code:
public partial class ChemischeAnalysen
    {
        public ChemischeAnalysen()
        {
            ChemischeAnalysenDetails = new HashSet<ChemischeAnalysenDetails>();
        }

        public int HeaderId { get; set; }
        public DateTime? Datum { get; set; }
        public string Bezeichung { get; set; }
        public string Anmerkung { get; set; }
        public string Gerät { get; set; }
        public string Kategorie { get; set; }

        public virtual ICollection<ChemischeAnalysenDetails> ChemischeAnalysenDetails { get; set; }
    }

C#-Code:
public partial class ChemischeAnalysenDetails
    {
        public int Id { get; set; }
        public string Element { get; set; }
        public decimal? Wert { get; set; }
        public int? ChemieId { get; set; }

        public virtual ChemischeAnalysen Chemie { get; set; }
    }
}

MGernot hat dieses Bild (verkleinerte Version) angehängt:
GridFull.png
Volle Bildgröße

Neuer Beitrag 28.09.2019 19:06 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
MGernot MGernot ist männlich
myCSharp.de-Mitglied

Dabei seit: 22.02.2009
Beiträge: 8

Themenstarter Thema begonnen von MGernot

MGernot ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo Witte,
danke für die Antwort. Würdest Du diesen Artikel zum Thema empfehlen, den ich im Forum entdeckt habe, oder gibt es zum Thema Viewmodel noch bessere Tutorials/Bücher?
 https://www.codingfreaks.de/2017/08/14/w...nsetzen-teil-5/

Danke
Neuer Beitrag 28.09.2019 19:11 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
MrSparkle MrSparkle ist männlich
myCSharp.de-Team

avatar-2159.gif


Dabei seit: 16.05.2006
Beiträge: 5.507
Herkunft: Leipzig


MrSparkle ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zu MVVM gibt es hier diesen Artikel:  [Artikel] MVVM und DataBinding. Das ist aber erst dann interessant, wenn die Daten auch geändert werden sollen. Solange sie nur angezeigt werden sollen, geht es auch so.

Nur ergibt die Ansicht keinen Sinn. Jeder Eintrag in deiner Liste hat ja mehrere Elemente, ChemieIDs etc.

Edit: Achso, ich glaube, jetzt verstehe ich es:

C#-Code:
var analysen = context.ChemischeAnalysenDetails
   .Include(s => s.Chemie)
   .ToList();
Neuer Beitrag 28.09.2019 19:33 Beiträge des Benutzers | zu Buddylist hinzufügen
MGernot MGernot ist männlich
myCSharp.de-Mitglied

Dabei seit: 22.02.2009
Beiträge: 8

Themenstarter Thema begonnen von MGernot

MGernot ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo,
ja das war ein dummes Beispiel jetzt. Also ChemischeAnalysen representiert einen Header für eine Analyse, ChemischeAnalysenDetails beinhaltet alle unter diesem Header gemessenen Elemente:
Also eigentlich ware das eine Master->Detail ansicht, nur möchte ich in erstem Schritt nur eine flache Liste.

Edit: Toller Artikel, Mr. Sparkle. Den werde ich in jedem Fall durcharbeiten!

MGernot hat dieses Bild (verkleinerte Version) angehängt:
SichtNeu.png
Volle Bildgröße

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von MGernot am 28.09.2019 19:57.

Neuer Beitrag 28.09.2019 19:49 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
MGernot MGernot ist männlich
myCSharp.de-Mitglied

Dabei seit: 22.02.2009
Beiträge: 8

Themenstarter Thema begonnen von MGernot

MGernot ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo Leute,
danke nochmal für eure Hilfe.Ich habe die Sache jetzt mal so mit JOIN gelöst, damit ich mal ein Erfolgserlebnis habe ;-) Bin immer wieder erstaunt, wie mächtig LINQ ist.
Soll man aber offensichtlich auch so nicht machen, sondern EF Core navigation properties verwenden.

C#-Code:
  var analysis = (from a in context.ChemischeAnalysen
                                join p in context.ChemischeAnalysenDetails
                                on a.HeaderId equals p.ChemieId
                                select new
                                {
                                    Datum = a.Datum,
                                    Bezeichung = a.Bezeichung,
                                    Anmerkung = a.Anmerkung,
                                    Gerät = a.Gerät,
                                    Kategorie = a.Kategorie,
                                    Element = p.Element,
                                    Wert = p.Wert

                                }).ToList();

Ich merke jetzt das ich von diesen Technologien und Entwicklermuster viel zu wenig verstehe, um irgendwas sinnvolles auf die Beine zu stellen.

Danke, vorerst und schöne Grüße aus Österreich.

MGernot hat dieses Bild (verkleinerte Version) angehängt:
TableSolved.png
Volle Bildgröße

Neuer Beitrag 29.09.2019 11:48 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Abt
myCSharp.de-Team

avatar-4119.png


Dabei seit: 20.07.2008
Beiträge: 14.280
Herkunft: Stuttgart/Stockholm


Abt ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Tipp: Wenn Du schon teilweise Deutsch programmierst, was alles andere als eine gute Idee ist, dann lass bitte wenigstens die Umlaute weg.
Es funktioniert zwar theoretisch; aber EF hat das zumindest in der Vergangenheit nicht immer gemocht.
Neuer Beitrag 29.09.2019 16:46 Beiträge des Benutzers | zu Buddylist hinzufügen
MGernot MGernot ist männlich
myCSharp.de-Mitglied

Dabei seit: 22.02.2009
Beiträge: 8

Themenstarter Thema begonnen von MGernot

MGernot ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo Abt,
ja danke für den Tip,werde ich in Zukunft vermeiden. Das ist so eine dumme Angewohnheit, die ich mir leider bei der VBA Programmierung eingehandelt habe.
Neuer Beitrag 29.09.2019 18:33 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
MorphieX MorphieX ist männlich
myCSharp.de-Mitglied

Dabei seit: 06.02.2012
Beiträge: 184
Entwicklungsumgebung: VS 2015 Community
Herkunft: Rahden


MorphieX ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Ich wundere mich gerade, dass noch gar nicht der Einwand kam, dass Datenbank Entitäten nicht an die UI gebunden werden, sondern dafür ViewModels benutzt werden sollten. verwundert
Neuer Beitrag 30.09.2019 07:35 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Abt
myCSharp.de-Team

avatar-4119.png


Dabei seit: 20.07.2008
Beiträge: 14.280
Herkunft: Stuttgart/Stockholm


Abt ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Wurde implizit bereits durch den Hinweis auf mvvm gemacht.
Und wenn man nur liest ist das eben nur halb so schlimm.
Neuer Beitrag 30.09.2019 10:54 Beiträge des Benutzers | zu Buddylist hinzufügen
Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum Der Startbeitrag ist älter als ein Jahr.
Der letzte Beitrag ist älter als ein Jahr.
Antwort erstellen


© Copyright 2003-2020 myCSharp.de-Team | Impressum | Datenschutz | Alle Rechte vorbehalten. | Dieses Portal verwendet zum korrekten Betrieb Cookies. 21.10.2020 17:45