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 » Datentechnologien » Relationale Datenabfrage per 'Include' in EFCore liefert leeres Objekt
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | Thema zu Favoriten hinzufügen

Antwort erstellen
Zum Ende der Seite springen  

Relationale Datenabfrage per 'Include' in EFCore liefert leeres Objekt

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

Dabei seit: 09.02.2015
Beiträge: 127
Entwicklungsumgebung: Visual Studio 2013


GeneVorph ist offline

Relationale Datenabfrage per 'Include' in EFCore liefert leeres Objekt

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

verwendetes Datenbanksystem: EntityFrameworkCore / SQLite

Hallo,

Ich habe in meiner wpf-Anwendung folgende Models:

C#-Code:
public class SchoolClass : ISchoolClassData
    {
        [Required]
        public int SchoolClassId { get; set; }

        [Required]
        public SchoolClassInternal SchoolClassInternals { get; set; } = new SchoolClassInternal();
    }

C#-Code:
public class SchoolClassInternal : ISchoolClassInternal
    {
        [Required]
        public int SchoolClassInternalId { get; set;}

        [Required]
        [MaxLength(64)]
        public string SchoolClassLabel { get; set; }

        [MaxLength(64)]
        public string SchoolClassLevel { get; set; }

        [MaxLength(64)]
        public string SchoolClassHead { get; set; }


        public ObservableCollection<Student> ClassStudents { get; set; } = new ObservableCollection<Student>();

    }

Wenn ich ein SchoolClass-Objekt erstelle und es an die SQLite-Datenbank übergebe, dann finde ich die übergebenen Daten dort wieder. Beim Lesen der Daten jedoch sind die Properties von SchoolClassInternals leer. Meine Methode:

C#-Code:
public static List<SchoolClass> GetAllClasses()
        {
            List<SchoolClass> _entity = new List<SchoolClass>();

            using (var context = new DataBaseContext())
            {
                if (context.SchoolClasses.Any())
                {
                    _entity = context.SchoolClasses
                                                                 .Include(c => SchoolClassInternals)
                                                                 .ToList();
                }

                return _entity;

            }

Es werden zwar die richtigen SchoolClass-Objekte zurückgegeben, deren SchoolClassInternals-Properties sind jedoch leer (SchoolClassInternalId, SchoolClassInternalLabel, SchoolClassInternalLevel, SchoolClassInternalHead).

Ich habe mal den UP-Part der Migration kopiert - soweit ich das interpretieren kann, wurden alle Indizes richtig zugeordnet

C#-Code:
protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.CreateTable(
                name: "Adresses",
                columns: table => new
                {
                    AdressId = table.Column<int>(type: "INTEGER", nullable: false)
                        .Annotation("Sqlite:Autoincrement", true),
                    Street = table.Column<string>(type: "TEXT", maxLength: 128, nullable: true),
                    PostalCode = table.Column<string>(type: "varchar(12)", maxLength: 10, nullable: true),
                    City = table.Column<string>(type: "TEXT", maxLength: 128, nullable: true)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_Adresses", x => x.AdressId);
                });

            migrationBuilder.CreateTable(
                name: "Educationals",
                columns: table => new
                {
                    EducationalId = table.Column<int>(type: "INTEGER", nullable: false)
                        .Annotation("Sqlite:Autoincrement", true),
                    ClassLabel = table.Column<string>(type: "TEXT", maxLength: 64, nullable: false),
                    ClassLevel = table.Column<string>(type: "TEXT", maxLength: 64, nullable: true),
                    EducationalProgram = table.Column<string>(type: "TEXT", maxLength: 64, nullable: true)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_Educationals", x => x.EducationalId);
                });

            migrationBuilder.CreateTable(
                name: "Personals",
                columns: table => new
                {
                    PersonalId = table.Column<int>(type: "INTEGER", nullable: false)
                        .Annotation("Sqlite:Autoincrement", true),
                    FirstName = table.Column<string>(type: "TEXT", maxLength: 128, nullable: false),
                    LastName = table.Column<string>(type: "TEXT", maxLength: 128, nullable: false),
                    FullName = table.Column<string>(type: "TEXT", maxLength: 128, nullable: true),
                    DateOfBirth = table.Column<string>(type: "varchar(15)", maxLength: 15, nullable: true),
                    Gender = table.Column<string>(type: "TEXT", maxLength: 20, nullable: true),
                    PhoneNumber = table.Column<string>(type: "varchar(128)", maxLength: 128, nullable: true)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_Personals", x => x.PersonalId);
                });

            migrationBuilder.CreateTable(
                name: "SchoolClassInternals",
                columns: table => new
                {
                    SchoolClassInternalId = table.Column<int>(type: "INTEGER", nullable: false)
                        .Annotation("Sqlite:Autoincrement", true),
                    SchoolClassLabel = table.Column<string>(type: "TEXT", maxLength: 64, nullable: false),
                    SchoolClassLevel = table.Column<string>(type: "TEXT", maxLength: 64, nullable: true),
                    SchoolClassHead = table.Column<string>(type: "TEXT", maxLength: 64, nullable: true)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_SchoolClassInternals", x => x.SchoolClassInternalId);
                });

            migrationBuilder.CreateTable(
                name: "SchoolClasses",
                columns: table => new
                {
                    SchoolClassId = table.Column<int>(type: "INTEGER", nullable: false)
                        .Annotation("Sqlite:Autoincrement", true),
                    SchoolClassInternalsSchoolClassInternalId = table.Column<int>(type: "INTEGER", nullable: true)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_SchoolClasses", x => x.SchoolClassId);
                    table.ForeignKey(
                        name: "FK_SchoolClasses_SchoolClassInternals_SchoolClassInternalsSchoolClassInternalId",
                        column: x => x.SchoolClassInternalsSchoolClassInternalId,
                        principalTable: "SchoolClassInternals",
                        principalColumn: "SchoolClassInternalId",
                        onDelete: ReferentialAction.Restrict);
                });

            migrationBuilder.CreateTable(
                name: "Students",
                columns: table => new
                {
                    StudentId = table.Column<int>(type: "INTEGER", nullable: false)
                        .Annotation("Sqlite:Autoincrement", true),
                    StudentPersonalPersonalId = table.Column<int>(type: "INTEGER", nullable: true),
                    StudentAdressAdressId = table.Column<int>(type: "INTEGER", nullable: true),
                    StudentEducationalEducationalId = table.Column<int>(type: "INTEGER", nullable: true),
                    SchoolClassInternalId = table.Column<int>(type: "INTEGER", nullable: true)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_Students", x => x.StudentId);
                    table.ForeignKey(
                        name: "FK_Students_Adresses_StudentAdressAdressId",
                        column: x => x.StudentAdressAdressId,
                        principalTable: "Adresses",
                        principalColumn: "AdressId",
                        onDelete: ReferentialAction.Restrict);
                    table.ForeignKey(
                        name: "FK_Students_Educationals_StudentEducationalEducationalId",
                        column: x => x.StudentEducationalEducationalId,
                        principalTable: "Educationals",
                        principalColumn: "EducationalId",
                        onDelete: ReferentialAction.Restrict);
                    table.ForeignKey(
                        name: "FK_Students_Personals_StudentPersonalPersonalId",
                        column: x => x.StudentPersonalPersonalId,
                        principalTable: "Personals",
                        principalColumn: "PersonalId",
                        onDelete: ReferentialAction.Restrict);
                    table.ForeignKey(
                        name: "FK_Students_SchoolClassInternals_SchoolClassInternalId",
                        column: x => x.SchoolClassInternalId,
                        principalTable: "SchoolClassInternals",
                        principalColumn: "SchoolClassInternalId",
                        onDelete: ReferentialAction.Restrict);
                });

            migrationBuilder.CreateIndex(
                name: "IX_SchoolClasses_SchoolClassInternalsSchoolClassInternalId",
                table: "SchoolClasses",
                column: "SchoolClassInternalsSchoolClassInternalId");

            migrationBuilder.CreateIndex(
                name: "IX_Students_SchoolClassInternalId",
                table: "Students",
                column: "SchoolClassInternalId");

            migrationBuilder.CreateIndex(
                name: "IX_Students_StudentAdressAdressId",
                table: "Students",
                column: "StudentAdressAdressId");

            migrationBuilder.CreateIndex(
                name: "IX_Students_StudentEducationalEducationalId",
                table: "Students",
                column: "StudentEducationalEducationalId");

            migrationBuilder.CreateIndex(
                name: "IX_Students_StudentPersonalPersonalId",
                table: "Students",
                column: "StudentPersonalPersonalId");
        }

Habe ich etwas offensichtliches übersehen?

Gruß
Vorph
Neuer Beitrag 23.11.2020 15:39 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
HansFred
myCSharp.de-Mitglied

Dabei seit: 19.10.2020
Beiträge: 47


HansFred ist offline

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

du kannst keine frontend modelle in der datenbank nutzen

und sollst das auch nicht
 [Artikel] Drei-Schichten-Architektur
Neuer Beitrag 23.11.2020 15:41 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
dannoe
myCSharp.de-Mitglied

Dabei seit: 24.11.2015
Beiträge: 120
Entwicklungsumgebung: VS2005-VS2017


dannoe ist offline

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

Welche Version von EF Core benutzt du?

Edit:
Versuch auch mal deine Navigation Property nicht mit new() zu initialisieren.

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von dannoe am 23.11.2020 15:50.

Neuer Beitrag 23.11.2020 15:48 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
FZelle
myCSharp.de-Poweruser/ Experte

Dabei seit: 23.04.2004
Beiträge: 9.879


FZelle ist offline

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

Eher keine ObservableCollection benutzen.
Die braucht man sowieso nicht im DAL
Neuer Beitrag 23.11.2020 17:07 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.572
Herkunft: Leipzig


MrSparkle ist offline

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

Zitat von GeneVorph:
Habe ich etwas offensichtliches übersehen?

Ja. Du solltest dir mal ein Einführungs-Tutorial von EF Core anschauen, bevor du loslegst. Da ist alles erklärt, was du hier versuchst.
Neuer Beitrag 23.11.2020 17:30 Beiträge des Benutzers | zu Buddylist hinzufügen
GeneVorph GeneVorph ist männlich
myCSharp.de-Mitglied

Dabei seit: 09.02.2015
Beiträge: 127
Entwicklungsumgebung: Visual Studio 2013

Themenstarter Thema begonnen von GeneVorph

GeneVorph ist offline

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

OK, erst Mal vielen Dank für eure Antworten! Bevor ich im Einzelnen antworte ganz kurz zum Problem:
- ich konnte es nun "lösen", indem ich eine foreach-Schleife nutze. Mein Code sieht nun so aus:

C#-Code:
public static List<SchoolClass> GetAllClasses()
        {
            List<SchoolClass> _entity = new List<SchoolClass>();

            using (var context = new DataBaseContext())
            {
                if (context.SchoolClasses.Any())
                {
                    _entity = context.SchoolClasses.Include(ci => ci.SchoolClassInternals).ToList();

                    foreach (SchoolClass sc in _entity)
                    {
                        sc.SchoolClassInternals = context.SchoolClassInternals.Where(s => s.SchoolClassInternalId == sc.SchoolClassId).FirstOrDefault();
                    }
                }

                return _entity;

            }

Durch die Include-Methode wird (bzw. wurde auch vorher schon) das SchoolClassInternals-Property hinzugefügt - nur wurden seine Property-Daten nicht geladen. Ich dachte, das wäre mit Include abgehakt...

Und damit kommen wir schon zu

Zitat:
du kannst keine frontend modelle in der datenbank nutzen
und sollst das auch nicht
[Artikel] Drei-Schichten-Architektur

Können schon - aber es leuchtet ein, dass es eine schlechte Idee ist. Wird in der nächsten Überarbeitung behoben.

Zitat:
Welche Version von EF Core benutzt du?

Edit:
Versuch auch mal deine Navigation Property nicht mit new() zu initialisieren.

Version 5.0.0 --> habe new() beim Navigation-Property entfernt (es ändert aber nichts am eigentlichen Problem).

Zitat:
Eher keine ObservableCollection benutzen.
Die braucht man sowieso nicht im DAL

Auch richtig - ich dachte mir schon, dass mein Code derzeit höchst unsexy ist ;) Ich versuche gerade alles, was ich online finden konnte (z. B. auf YouTube von Kanälen wie AngelSix, IAMTimCorey) aber auch zwei Udemy-Kursen und sämtlichen Blogs irgendwie sinnvoll zusammen zu tragen. Leider ist es nicht ganz einfach und nicht in ein paar Monaten machbar. Das wird wohl Jahre dauern, bis da wirklich "Profi-Code" drauß wird.
Leider verwenden viele Beispiele kein MVVM, andere pfeifen (aus Gründen der Einfachheit) auf DAL, eben um "nur mal kurz was zu zeigen" und dann muss man sich das aus unzähligen anderen Quellen zusammenstoppeln.

Zitat:
Ja. Du solltest dir mal ein Einführungs-Tutorial von EF Core anschauen, bevor du loslegst. Da ist alles erklärt, was du hier versuchst.

Kennst du denn ein gutes? Ich habe eines auf Udemy gefunden v. Mosh Hamedami, der auch auf YouTube aktiv ist. Es ist natürlich nahezu unmöglich zu sagen ob es denn "gut" ist (dazu hätte ich ja andere noch im Vergleich sehen müssen). Seine Schwäche ist, dass relationale Datenbezüge halt nur angekrazt werden - da konnte ich bei Tim Corey mehr finden; der übt aber eher Kritik an EF und so versuche ich halt das Beste aus beiden Welten zu generieren.

Gruß vorph
Neuer Beitrag 23.11.2020 20:17 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
GeneVorph GeneVorph ist männlich
myCSharp.de-Mitglied

Dabei seit: 09.02.2015
Beiträge: 127
Entwicklungsumgebung: Visual Studio 2013

Themenstarter Thema begonnen von GeneVorph

GeneVorph ist offline

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

Zitat von dannoe:
Welche Version von EF Core benutzt du?

Edit:
Versuch auch mal deine Navigation Property nicht mit new() zu initialisieren.

Halt! Ich nehme alles zurück und behaupte das Gegenteil! Gendau DAS war scheinbar das Problem - ich hatte es nur beim ersten Mal mit der falschen Methode getestet!

Nächster Task: eine gescheite DataAccessLayer...

vielen Dank!
Neuer Beitrag 23.11.2020 20:41 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
FZelle
myCSharp.de-Poweruser/ Experte

Dabei seit: 23.04.2004
Beiträge: 9.879


FZelle ist offline

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

Und tu dir einen gefallen, lass das mit den Tutorials auf YT, da gibt es sehr wenig gute.

Channel9 ist die deutlich bessere Wahl.
Neuer Beitrag 24.11.2020 17:10 Beiträge des Benutzers | zu Buddylist hinzufügen
Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum
Antwort erstellen


© Copyright 2003-2020 myCSharp.de-Team | Impressum | Datenschutz | Alle Rechte vorbehalten. | Dieses Portal verwendet zum korrekten Betrieb Cookies. 06.12.2020 01:56