sql >> Databáze >  >> RDS >> Sqlserver

Aktualizujte hodnotu primárního klíče pomocí entity framework

Mám Ph.D. v cs - v oblasti databází, takže tato odpověď bude trochu jiná než pohled programátorů. Při vší úctě k Oliveru Hanappimu se klíč může změnit a občas se také změní, pokud to není klíč náhradní. Např. Přirozený klíč nebo složený klíč. Například. Je možné si nechat změnit své SSN v USA. Ale mnoho programátorů v průběhu let by to považovalo za neměnný klíč a jako takový jej používali. Mnohem běžnější je změnit složený primární klíč složený z cizích klíčů.

Mám co do činění s databází, která má ternární vztah. Konkrétně tři entity (s cizími klíči jsou náhradní primární klíče v příslušných tabulkách). Chcete-li však zachovat vztah mezi dvěma entitami při změně třetí entity vyžaduje změna části primárního klíče průnikové tabulky (nazývané také čistá tabulka spojení na MSDN). Toto je platný návrh a lze jej vylepšit pouze odstraněním průnikové tabulky ternárních vztahů a jejím nahrazením dvěma tabulkami binárních vztahů (které mohou mít své vlastní náhradní klíče). EF by to zvládl v pohodě. Tato změna designu by vytvořila model (Mnoho->mnoho)->mnoho nebo Rodič1-Rodič2 -> Dítě-vnuk (pokud to není jasné, přečtěte si příklad níže). Rámec entit by s tím fungoval dobře, protože každý vztah je skutečně vztahem jedním z mnoha. Ale z pohledu DB je to šílený design. Dovolte mi ukázat vám příklad proč.

Vezměte v úvahu, že kurz, třída a instruktor jsou ve třídě vzájemně propojeni. Třída by mohla obsahovat:CourseID, ClassroomID, InstructorID jako cizí klíče a obsahovat složený primární klíč včetně všech tří. Přestože jde o jasný, stručný ternární model (3cestný vztah), mohli bychom jej rozdělit na binární vztahy. To by dalo dvě průsečíkové tabulky. Přidání náhradních klíčů uspokojí EF následovně:

Třída (SurrogateKeyClass , ID instruktora , CourseID )

ClassRoomUsed(SurrogateKeyClassroomUsed , SurrogateKeyClass , ClassRoomID )

Problém s tímto návrhem je, že bychom mohli mít stejný kurz a instruktora spojené vícekrát, čemuž se předchozí model vyhýbá. Abyste se tomuto problému vyhnuli, můžete do databáze přidat omezení pro jedinečnost dvou polí ID, ale proč byste to chtěli dělat, když se pro začátek zabýváte pouze náhradními klíči? Toto řešení by však fungovalo nejlépe, jak mohu říct. Toto však není návrh logické databáze kvůli nepřirozenému jedinečnému omezení vyžadovanému v DB.

ALE, pokud nechcete svou databázi změnit nebo ji nemůžete změnit, zde je druhé řešení :Průnikové/asociační tabulky jsou právě to, odkazy spojující dvě nebo více entit dohromady. Pokud se některá změní, odstraňte přidružení a znovu vytvořte nové, které má příslušné cizí klíče (vlastnosti navigace). To znamená, že v žádném ze vztahů nebudete moci vyžadovat podřízené entity, ale to je velmi běžné.

Navrhoval bych, aby Entity Framework (v budoucnu) umožnil těm z nás, kteří umí navrhnout elegantní DB model, měnit části klíčů v průsečíkových/asociačních tabulkách, kdy chceme!

Další příklad zdarma:

Zvažte asociaci student, kurz, ročník. Studenti jsou spojeni s kurzem prostřednictvím známky. Obvykle se jedná o mnoho až mnoho asociací mezi studentem a kurzem s dalším polem v asociační tabulce s názvem grade (asociační tabulky mají data užitečného zatížení, jako je grade, průsečíkové tabulky nemají užitečné zatížení a jsou v MSDN označovány jako čistě spojené tabulky na pronájem na jednom místě):

Student(StudentID , ....)

Kurz(ID kurzu , ...)

Přijímám(StudentID , CourseID , stupeň)

Pokud někdo udělá chybu při zadávání dat z rozbalovací nabídky a zařadí studenta do nesprávné třídy, chcete, aby to později změnil tak, že znovu vybere rozbalovací nabídku a vybere jiný kurz. Na pozadí budete muset odstranit objekt EF z tabulky Taking a znovu jej vytvořit, aniž byste ztratili známku, pokud nějaká existuje. Stačí změnit cizí klíč CourseID vypadá jako lepší alternativa. Vymyslete si vlastní asociaci, pokud se vám tato zdá vymyšlená, ale jako profesorovi to pro mě bylo přirozené.

Závěr:Když máte řetězec vztahů, může být lepší nepovolit kaskádování a/nebo změnu FK, ale existují rozumné/logické scénáře, kde je to potřeba, i když to není doporučeno jako osvědčený postup obecně .

Tento problém se může projevit s následujícími výjimkami v závislosti na tom, zda měníte vlastnost navigace nebo klíč v modelu:

Došlo k porušení omezení referenční integrity:Vlastnost primárního klíče, která je součástí omezení referenční integrity, nelze změnit, když je závislý objekt nezměněn, pokud není nastaven na hlavní objekt přidružení. Hlavní objekt musí být sledován a ne označen k odstranění.

Vlastnost 'X' je součástí klíčových informací o objektu a nelze ji upravit.



  1. scope_identity vs ident_current

  2. Obsahuje MS SQL Server hranice rozsahu?

  3. Odstraňte duplicitní řádky z malé tabulky

  4. Použití souboru .php ke generování výpisu MySQL