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
Warum sind Child-Properties trotz include in einer EFCore-Abfrage leer?
GeneVorph
myCSharp.de - Member



Dabei seit:
Beiträge: 160

Themenstarter:

Warum sind Child-Properties trotz include in einer EFCore-Abfrage leer?

beantworten | zitieren | melden

verwendetes Datenbanksystem: EntityFrameworkCore / SQLite

Hallo,

Ich habe in meiner wpf-Anwendung folgende Models:


 public class SchoolClass : ISchoolClassData
    {
        [Required]
        public int SchoolClassId { get; set; }

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


 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:


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

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



Dabei seit:
Beiträge: 49

beantworten | zitieren | melden

du kannst keine frontend modelle in der datenbank nutzen

und sollst das auch nicht
[Artikel] Drei-Schichten-Architektur
private Nachricht | Beiträge des Benutzers
dannoe
myCSharp.de - Member



Dabei seit:
Beiträge: 141

beantworten | zitieren | melden

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



Dabei seit:
Beiträge: 10042

beantworten | zitieren | melden

Eher keine ObservableCollection benutzen.
Die braucht man sowieso nicht im DAL
private Nachricht | Beiträge des Benutzers
MrSparkle
myCSharp.de - Team

Avatar #avatar-2159.gif


Dabei seit:
Beiträge: 5959
Herkunft: Leipzig

beantworten | zitieren | melden

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.
Weeks of programming can save you hours of planning
private Nachricht | Beiträge des Benutzers
GeneVorph
myCSharp.de - Member



Dabei seit:
Beiträge: 160

Themenstarter:

beantworten | zitieren | melden

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:

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



Dabei seit:
Beiträge: 160

Themenstarter:

beantworten | zitieren | melden

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!
private Nachricht | Beiträge des Benutzers
FZelle
myCSharp.de - Experte



Dabei seit:
Beiträge: 10042

beantworten | zitieren | melden

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

Channel9 ist die deutlich bessere Wahl.
private Nachricht | Beiträge des Benutzers