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 ist beim Auslesen der ForeignKey immer null (SqLite)?
Steven85
myCSharp.de - Member



Dabei seit:
Beiträge: 91

Themenstarter:

Warum ist beim Auslesen der ForeignKey immer null (SqLite)?

beantworten | zitieren | melden

Hallo zusammen,

ich bin gerade dabei mir EF Core anzueignen. Hier mein Beispiel mit Sqlite:


public class DataContext : DbContext
    {
        // Für die zu erzeugende Tabelle nach dem Code first Prinzip
        public DbSet<Person> Personen { get; set; }
        public DbSet<Geschlecht> Geschlechter { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlite(@"Data Source=D:\Daten\Steven IT\Daten\C# Entity Framework Core\Beispielanwendung Einfach\Beispielanwendung Einfach\Data\EntityFrameworkTutorial.db");
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Geschlecht>()
                .HasMany(g => g.Personen)
                .WithOne(p => p.Geschlecht);
        }
    }


public class Person
    {
        public int Id { get; set; }
        public string Vorname { get; set; }
        public string Nachname { get; set; }
        public Geschlecht Geschlecht { get; set; }
    }


public class Geschlecht
    {
        public int Id { get; set; }
        public string Bezeichnung { get; set; }
        public List<Person> Personen { get; set; }
    }


class Program
    {
        static void Main(string[] args)
        {
            using (var db = new DataContext())
            {
                var maennlich = new Geschlecht();
                maennlich.Bezeichnung = "Männlich";
                db.Geschlechter.Add(maennlich);

                var weiblich = new Geschlecht();
                weiblich.Bezeichnung = "Weiblich";
                db.Geschlechter.Add(weiblich);
                db.Personen.Add(person);

                person = new Person();
                person.Vorname = "Steven";
                person.Nachname = "S.";
                person.Geschlecht = maennlich;
                db.Personen.Add(person);

                person = new Person();
                person.Vorname = "Lisa";
                person.Nachname = "S.";
                person.Geschlecht = weiblich;
                db.Personen.Add(person);

                db.SaveChanges();
            }
            using (var db = new DataContext())
            {
                foreach (var person in db.Personen)
                {
                    Console.WriteLine($"{person.Id}. {person.Vorname} {person.Nachname} ({person.Geschlecht.Bezeichnung})");
                }
            }

            Console.ReadKey();
        }
    }

Das speichern klappt wunderbar, hier wird die Id des Geschlechts autom. hinzugefügt.
Jedoch ist beim Anzeigen der Daten in der Console person.Geschlecht = null. In der Datenbank sieht alles gut aus.
Könnt ihr mir sagen was hier noch fehlt?

Gruß Steven
Dieser Beitrag wurde 3 mal editiert, zum letzten Mal von Steven85 am .
private Nachricht | Beiträge des Benutzers
Palladin007
myCSharp.de - Member

Avatar #avatar-4140.png


Dabei seit:
Beiträge: 1427
Herkunft: Düsseldorf

beantworten | zitieren | melden

Schau mal da: Laden zugehöriger Daten - EF Core

Generell solltest Du deren Doku durcharbeiten, die ist wirklich gut.
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von Palladin007 am .
private Nachricht | Beiträge des Benutzers
Steven85
myCSharp.de - Member



Dabei seit:
Beiträge: 91

Themenstarter:

beantworten | zitieren | melden

Danke dir, das hat schon geholfen :)
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15618
Herkunft: BW

beantworten | zitieren | melden

Beginner Tipps, die einem das Lernen vereinfachen:
Verwende direkt .NET 5 und Nullable Reference Types; das spart einem viel Validierungsarbeit

public string Vorname { get; set; } = null!;

Wird zudem von Haus aus von EF5 unterstützt (wird auch im Schema beachtet)
EF arbeitet intern mit ICollection und dem HashSet

public ICollection<Person> Personen { get; set; } = new HashSet<Person>();
Ja, die Doku verwendet an manchen Stellen List - aber das ist eigentlich totaler Quatsch.

Verwende immer die async-Methoden, immer. Immer immer.

Verwende Explizite FK-Properties; vermeide die Attribute


 public Geschlecht Geschlecht { get; set; }
 public int GeschlechtId { get; set; }

 modelBuilder.Entity<Geschlecht>()
                .HasMany(g => g.Personen)
                .WithOne(p => p.Geschlecht)
                .HasForeignKey(p => p.GeschlechtId);
Besonders bei der Fehlersuche versteht man seinen eigenen Aufbau viel einfacher als wenn das ganze Magic Zeug da reinspielt.

Palladin007 hat aber absolut recht, dass die Doku sehr mächtig und insgesamt - bis auf eine Hand voll Dinge - qualitativ extrem gut ist.
90% aller Durchschnitts-Themen zu EF lassen sich von der Doku beantworten.
private Nachricht | Beiträge des Benutzers
Steven85
myCSharp.de - Member



Dabei seit:
Beiträge: 91

Themenstarter:

beantworten | zitieren | melden

Hi Abt,

das Thema mit await und async wollte ich mir separat ansehen, habe erstmal darauf verzichtet da ich noch nicht wirklich verstehe was da passiert, bzw. was es genau bringt. Könntest du es evtl. kurz beschreiben anhand eines kleinen Beispiels, oder mir evtl. ein gutes Tutorial dazu emphelen?

Und kannst du mir auch noch erklären wozu genau das dient? brauch man das Ausrufungszeichen hinter dem null?


public string Vorname { get; set; } = null!;

Gruß Steven
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15618
Herkunft: BW

beantworten | zitieren | melden

Wenn Du etwas nicht kennst, dann werf doch erstmal ein Blick in die Doku ;-)

Asynchrone Programmierung mit async und await
Nullable-Werttypen (C#-Referenz)

Macht ja wenig sinn 1:1 zu wiederholen, was auch in der Doku so steht :-)
private Nachricht | Beiträge des Benutzers
Steven85
myCSharp.de - Member



Dabei seit:
Beiträge: 91

Themenstarter:

beantworten | zitieren | melden

Schaue ich mir an, danke dir.
private Nachricht | Beiträge des Benutzers
Steven85
myCSharp.de - Member



Dabei seit:
Beiträge: 91

Themenstarter:

beantworten | zitieren | melden

Hi Abt,

habe mir die Doku zu async und await angesehen und auch bereits angewendet bzw. nachvollzogen.
Habe hierzu noch eine Frage. Du sagst ja ich soll immer die async Methoden verwenden, als z.b. so:


private static async void UseCase_QueryTypesAsync(DataContext dbContext)
        {
            // nur zur Demonstration ein kleines View, hier brauch man keine Migration
            var result = await dbContext.VW_Test.ToListAsync();
            Console.WriteLine(string.Join("\n", result));
        }

Aber was bringt es in diesem Fall? Hier wird doch sowieso nur der eine Aufruf gemacht? Oder ist dann die Methode ToListAsync an sich schon schneller?

Edit: Habe es gerade mal mit der Klasse Stopwatch gemessen (jeweils 5-6 mal). Ich brauche mit async und await im Schnitt 0,2 Sekunden länger.
Dieser Beitrag wurde 3 mal editiert, zum letzten Mal von Steven85 am .
private Nachricht | Beiträge des Benutzers
T-Virus
myCSharp.de - Member



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

beantworten | zitieren | melden

Da deine Methode async void "liefert", hat dein Code hier keinen Vorteil.
Dadurch läufst du auch Gefahr, dass dein Code nicht auf das Ende der Methode wartet bzw. warten kann.

Der Sinn und Zweck von async/await ist gerade der asynchrone Ablauf von Methode in Verbindung mit Tasks um diese auch steuern zu können bzw. korrekt auf diese warten zu können.
Schau dir am besten nochmal die Doku an und liefere dann Task anstelle von void zurück.

Wenn du mit asynchronen Methoden z.B. bei IO Aufgaben arbeitest, merkst du die Vorteile.
In Verbindung mit einer UI (WPF/Windows Forms), kann man dann durch asynchrone Programmierung mit asnyc/await das bekannte einfrieren der Anwendungung sauber lösen.

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
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15618
Herkunft: BW

beantworten | zitieren | melden

async/await hat große Vorteile die Ressourcen eines Systems effizient zu nutzen und blockierenden Code - wie er aktuell bei Dir ist - zu vermeiden.
Mit async/await kann man aber auch viel falsch machen, wenn man grundlegende Dinge nicht beachtet, wozu zB. der Pitfall async void gehört.
Avoid Async Void

Beachtet man die Grundzüge von async/await nicht, dann wirds Race Condition in Massen hageln und der Code wird ganz komisch Dinge machen.
Daher ist das ein super Thema mit dem Du beginnen kannst wirklich die Doku mal durchzuarbeiten, da dies wirklich notwendig ist.
Dann kann auch Dein Code davon profitieren.
private Nachricht | Beiträge des Benutzers
Palladin007
myCSharp.de - Member

Avatar #avatar-4140.png


Dabei seit:
Beiträge: 1427
Herkunft: Düsseldorf

beantworten | zitieren | melden

Ergänzend dazu:

Await, SynchronizationContext, and Console Apps

Mir hatte das sehr geholfen, die Hintergründe zu verstehen - allerdings weiß ich nicht mehr, welchen Wissensstand ich da hatte :D

Generell halte ich es beim Thema async/await für sehr wichtig, die Hintergründe wirklich verstanden zu haben, da hier viel "Magie" passiert, die man sonst kaum verstehen kann.
Aber überstürze es nicht, merk's dir bloß für später, wenn Du halbwegs damit umgehen kannst.

Einmal verstanden, stellt sich aber heraus, dass es doch gar nicht so viel Magie ist ;)
private Nachricht | Beiträge des Benutzers