sql >> Database teknologi >  >> RDS >> Sqlserver

Opdater primær nøgleværdi ved hjælp af entity framework

Jeg har en ph.d. i cs - inden for databaser, så dette svar vil være lidt anderledes end et programmørperspektiv. Med al respekt for Oliver Hanappi, en nøgle kan og ændrer sig af og til, hvis den ikke er en surrogatnøgle. For eksempel. En naturlig nøgle eller en sammensat nøgle. For eksempel. Det er muligt at få ændret dit SSN i ​​USA. Men mange programmører gennem årene ville betragte dette som en uforanderlig nøgle og bruge den som sådan. Det er meget mere almindeligt at ændre en sammensat primærnøgle, der består af fremmednøgler.

Jeg har at gøre med en database, der har et ternært forhold. Specifikt tre enheder (hvor fremmednøgler er primære surrogatnøgler i deres respektive tabeller). For at bevare forholdet mellem to entiteter og samtidig ændre den tredje enhed kræver ændre en del af skæringstabellen (også kaldet en ren jointabel på MSDN) primærnøgle. Dette er et gyldigt design og kan kun forbedres ved at fjerne den ternære relationsskæringstabel og erstatte den med to binære relationstabeller (der kan have deres egne surrogatnøgler). EF ville klare dette fint. Denne designændring ville gøre en (Mange->mange)->mange eller Forælder1-Forældre2 -> Barnebarn-model (hvis det ikke er klart, læs eksemplet nedenfor). Entity framework ville fungere fint med dette, da hvert forhold virkelig er et til mange forhold. Men det er et skørt design fra et DB-perspektiv. Lad mig vise dig et eksempel på hvorfor.

Overvej, at kursus, klasseværelse og underviser er forbundet med hinanden i en klasse. Klasse kunne omfatte:CourseID, ClassroomID, InstructorID som fremmednøgler og indeholde en sammensat primærnøgle inklusive alle tre. Selvom en klar, kortfattet ternær model (3-vejs forhold) kunne vi opdele den i binære relationer. Dette ville give to skæringstabeller. Tilføjelse af surrogatnøgler ville tilfredsstille EF som følger:

Klasse(SurrogateKeyClass , instruktør-id , Kursus-id )

ClassRoomUsed(SurrogateKeyClassroomUsed , SurrogateKeyClass , ClassRoomID )

Problemet med dette design er, at vi kunne have det samme kursus og instruktør tilknyttet flere gange, hvilket den tidligere model undgår. For at undgå dette problem kan du tilføje en begrænsning i databasen for entydighed af de to ID-felter, men hvorfor vil du gøre dette, når du kun har at gøre med surrogatnøgler til at starte med? Men denne løsning ville fungere så godt som jeg kan fortælle. Dette er dog ikke et logisk databasedesign på grund af den unaturlige unikke begrænsning, der kræves i DB.

MEN, hvis du ikke vil ændre din database eller ikke kan ændre din database, er her en anden løsning :Skærings-/tilknytningstabeller er netop det, links, der forbinder to entiteter eller flere sammen. Hvis en ændres, skal du slette tilknytningen og genskabe en ny, der har de passende fremmednøgler (navigationsegenskaber). Det betyder, at du ikke får lov til at kræve underordnede enheder i nogen af ​​relationerne, men det er ekstremt almindeligt.

Jeg vil foreslå, at Entity Framework (i fremtiden) giver os, der kan designe en elegant DB-model, mulighed for at ændre dele af nøgler i skærings-/tilknytningstabeller, når vi vil!

Et andet eksempel gratis:

Overvej en studerende, kursus, karakterforening. Eleverne tilknyttes et forløb via en karakter. Normalt er dette en mange til mange sammenhæng mellem studerende og et kursus med et ekstra felt i tilknytningstabellen kaldet karakter (tilknytningstabeller har nyttelastdata som karakter, skæringstabeller har ikke en nyttelast og omtales i MSDN som rene jointabeller på lejemål ét sted):

Elev(Student-ID , ....)

Kursus(Kursus-id , ...)

Tager (Student-ID , Kursus-id , karakter)

Hvis nogen laver en dataindtastningsfejl fra en rullemenu og placerer en elev i den forkerte klasse, vil du gerne have, at de ændrer det senere ved at vælge rullemenuen igen og vælge et andet kursus. I baggrunden skal du slette EF-objektet fra Taking-tabellen og genskabe det uden at miste en karakter, hvis der er en. Du skal blot ændre den udenlandske nøgle Kursus-ID virker som et bedre alternativ. Kom med din egen forening, hvis denne virker konstrueret, men som professor var det naturligt for mig.

Konklusion:Når du har en række relationer, kan det være bedre ikke at tillade cascading og/eller ændring af FK, men der findes rimelige/logiske scenarier, hvor det er nødvendigt, selvom det ikke anbefales som en bedste praksis i generelt .

Dette problem kan manifestere sig med følgende undtagelser afhængigt af, om du ændrer henholdsvis navigationsegenskaben eller nøgleegenskaben i modellen:

Der opstod en overtrædelse af referenceintegritetsbegrænsningen:En primær nøgleegenskab, der er en del af referenceintegritetsbegrænsningen, kan ikke ændres, når det afhængige objekt er Uændret, medmindre det indstilles til foreningens hovedobjekt. Hovedobjektet skal spores og ikke markeres til sletning.

Egenskaben 'X' er en del af objektets nøgleinformation og kan ikke ændres.



  1. Skrivning af læsbar kode til VBA – Prøv* mønster

  2. Opdel kommaseparerede værdier af en kolonne i række via Oracle SQL-forespørgsel

  3. hvordan man bruger check constraint i oracle

  4. Sådan øges filstørrelsen af ​​en datafil i SQL Server (T-SQL)