Avatar billede HobbyUdvikleren Nybegynder
13. november 2013 - 20:09 Der er 6 kommentarer og
1 løsning

Entity framework - relateret objekt oprettes i tabel

Jeg benytter code-fist entity framework, hvor jeg har en relation mellem tre klasser. Kunde, Kontaktperson, Titel.
Relationen Kunde har mange Kontaktperson. Kontaktperson har en Titel. Titel har mange Kontaktperson.  Titel kan betragtes her som en enum.

Mit problem er, at når jeg gemmer en ny Kunde inkl. ny relateret data, bliver Kunde, Kontaktpersoner og Titel indsat i database. Bortset fra Titel er dette som ønsket.
For at undgå at titel bliver oprettet i database, attacher jeg til kontekst hver titel for hver kontaktperson.  Hvis en kunde har flere kontaktpersoner med samme titel, får jeg en fejl med at der allerede er en titel i kontekst. For at undgå dette, tjekker jeg om titel allerede er i kontekst inden jeg attacher. Dermed får jeg ikke en fejl, og den første titel bliver ikke oprettet i databasen. Det gør den næste dog. Hvad kan jeg gøre?

Min kode er her:


using (var context = new DB())
            {
                foreach (Kontaktperson kp in KontaktpersonerForKunde)
                {
                   
                    if(!context.Title.Local.Any(e=> e.TitleId==kp.Title.TitleId))
                    {
                        context.Title.Attach(kp.Title);
                    }
            }
                context.Kunde.Add(this);
                context.SaveChanges();
            }
Avatar billede Syska Mester
13. november 2013 - 20:17 #1
1. Det lader til at du bruger en MEGET gammel version af EF, er dette korrekt?

( den indbyggede i VS er WAY OLD ) og hedder vist nok 4.0 og shovt nok kom med .NET 4.0 som kom med VS 2010.

EF er oppe på version 6 og du bør stoppe ASAP med at bruge den gamle version da der er mange bugs i den som ikke vil blive rettet. Performance er ringe i forhold til den nye.

Udover det kan jeg ikke lige helt gennemskue din kode da du ikke viser så meget af den, men giver som om det er en metode på en "Kunde" class siden du kan sige: context.Kunde.Add(this)

Hvilket ikke altid er smart med mindre du går efter ActiveRecord pattern. Men dermed har din data class stadig for meget viden om hvordan den selv virker.
Avatar billede HobbyUdvikleren Nybegynder
13. november 2013 - 20:29 #2
Ja, jeg kan se jeg benytter Version=5.0.0.0. Kan forsøge at opgradere og se om det vil løse mig problem. 

Ja, det er korrekt, klassen Kunde og et objekt af denne bliver gemt (add(this)). Objektet har reference til flere Kontaktperson objekter, som hver har reference til et Titel objekt.

Kan det hjælpe med et svar?java script: void(0);
Avatar billede Syska Mester
13. november 2013 - 21:08 #3
Umildbart hvis dine object kommer fra samme context, hvilket de burde, så skal du ikke attach igen.

Du må stadig have det orginale db object hvor de kommer fra, og på den måde kan du komme over med at du er fri for at attach dem igen.

Det burde også være muligt at sprøge et object om det allerede er attached. Kig eventuelt på: http://stackoverflow.com/questions/1715501/is-is-possible-to-check-if-an-object-is-already-attached-to-a-data-context-in-en

EF 5 eller 6 gør vist ikke den store forskel, men kig på det SO spørgsmål i linket over.
Avatar billede HobbyUdvikleren Nybegynder
13. november 2013 - 21:13 #4
Nu fik jeg opgraderet, men det gjorde ikke en forskel. Nej, jeg har ikke objekterne i context. Det er en webapplikation.  Jeg ser lige på dit link.
Avatar billede Syska Mester
13. november 2013 - 21:38 #5
Hvor har du den liste liste fra?

Siden den allerede har en title, så må den vel komme et eller andet sted fra.

Du bør måske gøre det den modsatte vej.

Se om din Title allerede er i din context,  hvis den ikke er, så bør du hente den ud og sætte din property på dit kunde object i stedet.

Så er jeg rimelig sikker på du kan undgå dette.
Avatar billede HobbyUdvikleren Nybegynder
13. november 2013 - 23:23 #6
Fandt løsningen her: http://stackoverflow.com/questions/7884887/prevent-entity-framework-to-insert-values-for-navigational-properties

Her benyttede jeg: First solution - use the same context for loading department and saving employee:

Dvs., at jeg for hver Titel for hver Kontaktperson, sætter reference direkte til Titel objektet hvormed den bliver tilføjet til Context. Sådan forstår jeg det..
Avatar billede Syska Mester
13. november 2013 - 23:41 #7
Altså præcis som jeg skrev i min forige indlæg, som jeg ikke helt er klar over om du har læst.

Men godt du fik det til at virke.

mvh
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester