Entity Framework - dodawanie nowych obiektów

0

Cześć,
posługuję się pierwszy raz Entity Framework i coś mi nie wychodzi:
mam klasę Pacjent (Patient), każdy pacjent ma 52 zęby (Teeth), listę zabiegów (itsTreatments), listę przyszłych zabiegów i listę chorób:

 
abstract public class Person
    {
        public string itsName { get; set; }
        public string itsSurname { get; set; }
        public string itsPESEL { get; set; }
        public Address itsAddress { get; set; }
        public string itsTelephone { get; set; }
        public string itsBirthDate { get; set; }
    }


    public class Patient : Person
    {
        public int PatientId { get; set; }
        private Tooth[] itsTeeth;
        public List<Treatment> itsTreatments { get; set; }
        public List<Treatment> itsTreatmentPlans { get; set; }
        public List<Disease> itsDiseases { get; set; }


        public Patient() { }

        public Patient(string name, string surname, string pesel, Address address, string tel, string birth)
        {
            itsName = name;
            itsSurname = surname;
            itsPESEL = pesel;
            itsAddress = address;
            itsTelephone = tel;
            itsBirthDate = birth;
            itsTreatments = new List<Treatment>();
            itsTreatmentPlans = new List<Treatment>();

            itsTeeth = new Tooth[52] {           new Tooth("18"), new Tooth("17"), new Tooth("16"), new Tooth("15"), new Tooth("14"), new Tooth("13"), new Tooth("12"), new Tooth("11"),
                                                 new Tooth("28"), new Tooth("27"), new Tooth("26"), new Tooth("25"), new Tooth("24"), new Tooth("23"), new Tooth("22"), new Tooth("21"),
                                                 new Tooth("38"), new Tooth("37"), new Tooth("36"), new Tooth("35"), new Tooth("34"), new Tooth("33"), new Tooth("32"), new Tooth("31"),
                                                 new Tooth("48"), new Tooth("47"), new Tooth("46"), new Tooth("45"), new Tooth("44"), new Tooth("43"), new Tooth("42"), new Tooth("41"),
                                                 new Tooth("55"), new Tooth("54"), new Tooth("53"), new Tooth("52"), new Tooth("51"),
                                                 new Tooth("65"), new Tooth("64"), new Tooth("63"), new Tooth("62"), new Tooth("61"),
                                                 new Tooth("75"), new Tooth("74"), new Tooth("73"), new Tooth("72"), new Tooth("71"),
                                                 new Tooth("85"), new Tooth("84"), new Tooth("83"), new Tooth("82"), new Tooth("81") };


        }

    }

    public class Tooth
    {
        public int ToothId { get; set; }
        public string ToothPosition { get; }

        private bool _hasCrown;
        private bool _isEndo;
        private bool _isExtracted;
        private bool _isCutting;
        private bool _isStopped;

        public virtual Patient itsPatient { get; set; }
    }

Jak widać, konstruktor klasy Patient tworzy tablicę 52 zębów. Klasa DbContext wygląda tak:

 
class PatientsDatabaseContext : DbContext
    {

        public DbSet<Patient> Pacjenci { get; set; }
        public DbSet<Tooth> Teeth { get; set; }
        public DbSet<Disease> Diseases { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {

            modelBuilder.Entity<Patient>()
                        .HasMany<Disease>(s => s.itsDiseases).WithMany();
            modelBuilder.Entity<Patient>()
                .HasMany<Treatment>(s => s.itsTreatments).WithOptional();
            modelBuilder.Entity<Patient>()
                .HasMany<Treatment>(s => s.itsTreatmentPlans).WithOptional();

        }
    }

Tworzę nowego pacjenta za pomocą ww. konstruktora i dołączam do bazy:

 

Database = new PatientsDatabaseContext();
Database.Pacjenci.Add(nowyPacjent);
Database.SaveChanges();

Pacjent, tj. jego imię, adres itd. się dodaje, ale zęby się nie dodają. Przy ponownej próbie wczytania danych gdy np. wywołam funkcję itsTreatments.Count() powstaje ArgumentNullException - obiekt itsTreatments, Teeth, nie istnieją w pacjencie.
Co robię nie tak?

1

Czy to co zrobiłeś to mapowanie z bazy danych jeden do jednego czy może dodawałeś coś od siebie do tego kodu? Bo ta lista zębów jest prywatna, a to bez sensu.
W EF jeżeli Pacjent posiada Zęby to powinna być wewnątrz klasy Patient kolekcja Teeth np: public virtual ICollection<Tooth> Teeth { get; set; }

Jak widzisz Tooth to tabela z bazy danych: public DbSet<Tooth> Teeth { get; set; } więc robienie wewnątrz klasy Patient tablicy zębów jest bez sensu, ponieważ jeżeli masz dobrze zrobione relacje na poziomie bazy danych to z automatu powinieneś mieć kolekcję zębów w pacjencie - to co wyżej napisałem.

PS: te przedrostki its powywalaj, bo fatalnie się czyta takie nazwy pól. Jak to pole / własność publiczna to zaczynaj ją z wielkiej litery i rób nie itsName tylko Name. :)

1

EF nie ustawi przecież wartości prywatnego pola.

Serio chciało Ci się to new Tooth() kopiować tyle razy? Nie prościej było w pętli zrobić?

P.S. każdy pacjent ma 52 zęby - jakiego gatunku są pacjenci?

0
grzesiek51114 napisał(a):

W EF jeżeli Pacjent posiada Zęby to powinna być wewnątrz klasy Patient kolekcja Teeth np: public virtual ICollection<Tooth> Teeth { get; set; }

Jak widzisz Tooth to tabela z bazy danych: public DbSet<Tooth> Teeth { get; set; } więc robienie wewnątrz klasy Patient tablicy zębów jest bez sensu, ponieważ jeżeli masz dobrze zrobione relacje na poziomie bazy danych to z automatu powinieneś mieć kolekcję zębów w pacjencie - to co wyżej napisałem.

Dziękuję, zaczęło działać, tj. zęby zapisują się w bazie. Nie wiem jednak co zrobić, żeby wczytały się do pacjenta po ponownym uruchomieniu programu. Robię:

Database = new PatientsDatabaseContext();
listaPacjentow = Database.Pacjenci;
 

Dane pacjentów się wyświetlają, ale zębów nie mają - null.

somekind napisał(a):

P.S. każdy pacjent ma 52 zęby - jakiego gatunku są pacjenci?

Dentyści mówią że tak jest ;)

grzesiek51114 napisał(a):

PS: te przedrostki its powywalaj, bo fatalnie się czyta takie nazwy pól. Jak to pole / własność publiczna to zaczynaj ją z wielkiej litery i rób nie itsName tylko Name.

Dzięki za sugestię, robię tak, bo taką sugerowali konwencję w jednej z książek o C++ :)

1
Anthus napisał(a):

Dane pacjentów się wyświetlają, ale zębów nie mają - null.

O ile mi wiadomo, Entity Framework nie obsługuje tablic. Użyj List<Tooth>.

Dentyści mówią że tak jest ;)

52 zęby można mieć przez całe życie, jeśli uwzględnimy mleczaki, ale nikt nie ma na raz więcej niż 32 zębów na raz.

W ogóle taki obiekt klasy ząb powinien przechowywać informacje o pozycji (dwa parametry) i rodzaj (siekacz, kieł, trzonowy), no i fakt, czy jest stały, czy mleczny. Chyba powinieneś rozbudować nieco swoją klasę.

1 użytkowników online, w tym zalogowanych: 0, gości: 1