Ultima actualizare: 2 martie 2017 | Creat: 22 mai 2014
Rezumat rapid
Am gasit informatii contradictorii cu privire la modul de actualizare a relatiilor de la multe la multe in cadrul entitatii. Prin urmare, am decis sa cercetez corect problema. Acest post impartaseste cu voi cercetarile mele.
Cred ca acum inteleg cum functioneaza cadrul de entitate cu relatii automate de la multe la multe si cum sa implementez propria mea tabela de legaturi, daca trebuie.
Am avut probleme la rezolvarea celei mai bune modalitati de a actualiza relatiile de la mai multi la multi in cadrul entitatii (denumit EF). Am sfarsit facand unele cercetari si am crezut ca altora ar putea sa vada ce am aflat.
In primul rand mediul in care lucrez:
- Folosesc EF 6.1 in modul Code First. Sunt destul de sigur ca ceea ce am gasit se aplica peste bord, dar am testat doar pe EF 6.1
- Lucrez intr-o aplicatie web (MVC 5), asa ca trebuie sa ma ocup de clase deconectate.
Daca doriti doar raspunsul rapid, atunci amenda partea 1 concluzie. escorte sex neprotejat sineps.org Concluziile au, de asemenea, un link catre un site web live, unde puteti vedea o relatie mult-la-multi folosita pentru real (cu acces si la sursa). Cu toate acestea merita sa cititi cateva dintre exemple, astfel incat sa intelegeti de ce functioneaza.
UPDATE 2017: Am scris o noua versiune a acestui articol pentru Entity Framework Core (EF Core) pentru a sarbatori lansarea cartii mele Entity Framework Core in Action.
EF Core NU functioneaza la fel ca EF6.x si noul articol ofera informatii despre cum sa gestionati relatiile dintre multe si multe din EF Core.
Partea 1: Utilizarea legaturii automate a EF a relatiilor dintre multe si multe
In acest exemplu, am legat pur si simplu acea eticheta si postare avand ICollection <Tag> Etichete in clasa Post si ICollection <Post> Postari in clasa Tag. Consultati proprietatile de navigare in Tag si Post in diagrama de mai jos:
Cursuri cadru pentru entitati de eticheta, postare si blog
Asa cum se explica in tutorialul Microsoft EF va crea un tabel de legatura numit TagPosts sau PostTags. Acest tabel de legaturi, pe care nu il vedeti niciodata, ofera numeroase la mai multe linkuri. In felul acesta, o postare nu poate avea niciunul la multe etichete, iar etichetele pot fi in niciunul la multe postari.
Deci actiunea pe care vreau sa o execut este sa schimb etichetele de pe o postare. Pare simplu si este in acest exemplu daca aveti grija la cateva lucruri. escorte tomis nord antonellaspada.adam-eve-sex-toys.com
Primul raspuns: actualizati relatia mult-la-multi in stare conectata
Mai jos sunt prezentate doua teste de unitate care nu trebuie sa va faceti griji pentru clasele deconectate. Acestea sunt puncte de plecare bune, deoarece este important sa cunoastem modul in care EF face cel mai simplu caz. Primul test adauga o eticheta la o postare in timp ce al doilea inlocuieste etichetele curente cu un set nou. Retineti ca prima postare incepe cu doua etichete; ‘bun’ si ‘urat’.
[Test] public void Check25UpdatePostToAddTagOk () {folosind (var db = new SampleWebAppDb ()) {// SETUP var badTag = db.Tags.Single (x => x.Slug == “rau”); var firstPost = db.Posts.Primul (); // ATTEMPT db.Entry (firstPost) . escorte botosani site:nimfomane.com d-click.sociesc.org.br Collection (x => x.Tags) .Load (); firstPost.Tags.Add (badTag); db.SaveChanges (); // VERIFICA primulPost = db.Blogs.Include (x => x.Posts.Select (y => y.Tags)). escorte chiajna lespooch.com First () .Posts.First (); firstPost.Tags.Count.ShouldEqual (3); }} [Test] public void Check26ReplaceTagsOk () {folosind (var db = new SampleWebAppDb ()) {// SETUP var firstPost = db.Posts.First (); var tagsNotInFirstPostTracked = db.Tags.Where (x => x.Posts. escorte sexy buzau publish.co All (y => y.PostId! = firstPost.PostId)) .ToList (); // ATTEMPT db.Entry (firstPost) .Collection (x => x.Tags) .Load (); firstPost.Tags = tagsNotInFirstPostTracked; db. Salveaza modificarile(); // VERIFICA primulPost = db.Blogs. forum escorte botosani themeehans.us Include (x => x.Posts.Select (y => y.Tags)). First () .Posts.First (); firstPost.Tags.Count.ShouldEqual (1); }}
Acum, ar trebui sa vedeti cele doua linii importante (linia 11 si 34) care incarca etichetele actuale in postare. Acest lucru este foarte important, deoarece incarca etichetele actuale ale postarii, astfel incat EF sa poata urmari cand sunt schimbate. publi 24 escorte brasov jam-hot.com
- escorte pitesti dominare
- escorte maremures
- escorte la tine acasa
- escorte…brasov
- escorte medias sibiu
- escorte prhova
- escorte .com
- escorte eftine bucuresti
- escorte kaufland
- escorte focaani
- escorte mangalia site:nimfomane.com
- escorte..pascani
- escorte craiova marina
- publi 24 escorte arges
- form escorte constanta
- escorte constanta non stop
- escorte luica
- recomandari escorte brasov
- escorte nonstop galati
- escorte simleu
Exista o serie de alternative la utilizarea .Load (), care ar functiona.
- Adaugati .Include () atunci cand incarcati postarile, de exemplu,
var firstPost = db.Posts.Include (post => post.Tags) .Primul () - Faceti proprietatea
Eticheta in clasa Post virtuala, de ex. Colectia virtuala publica <Tag> Etichete {get; a stabilit; }
Dupa ce ati utilizat .Load (), .Include () sau o proprietate virtuala, atunci EF urmareste datele si apoi face toate lucrarile pentru a elimina randurile TagLink. sexi net escorte ibew1st.org Acest lucru este foarte inteligent si foarte util.
Am vrut sa-mi dovedesc cu adevarat ca descoperirile mele au fost corecte, asa ca am scris un alt Test Unit pentru a testa cazul esecului. Testul de unitate de mai jos arata in mod concludent ca, daca nu incarcati etichetele curente, va obtine un rezultat gresit. Asa cum am spus mai devreme, prima postare a inceput cu etichetele „bune” si „urate” si ar fi trebuit sa termine cu NUMAI eticheta „proasta”. Cu toate acestea, testul unitatii arata ca a ajuns cu toate cele trei.
[Test] public void Check05ReplaceAllTagsNoIncludeBad () {folosind (var db = new MyDbContext ()) {// SETUP var snap = new DbSnapShot (db); var firstPost = db.Posts.Primul (); var badTag = db.Tags.SingleOrDefault (x => x.Slug == “rau”); // ATTEMPT firstPost. anunturi escorte bacau nevadastrip.com Tags = Lista noua {badTag}; db.SaveChanges (); // VERIFICARE snap.CheckSnapShot (db, 0, 1); var readPost = db.Posts.Include (x => x.Tags) .SingleOrDefault (x => x.PostId == firstPost.PostId); CollectionAssert.AreEquivalent (nou [] {“bun”, “rau”, “urat”}, readPost.Tags. escorte. sibiu jru.campusguru.com Select (x => x.Slug)); }}
Dupa cum puteti vedea din exemplul de mai sus, s-a incheiat cu toate cele trei, ceea ce nu este raspunsul corect.
Al doilea raspuns: actualizati relatia de la multi la multi in stare deconectata
Cand lucrati cu o aplicatie web precum MVC, o actualizare se face in doua etape. In primul rand, datele curente sunt trimise utilizatorului care le actualizeaza. In al doilea rand, atunci cand utilizatorii apasa transmit noile date sunt trimise inapoi, dar acum sunt deconectate de la baza de date, adica EF nu il urmareste. Acest lucru face pentru un caz ceva mai complicat, dar totusi destul de usor de manevrat.
Mai jos este metoda mea pentru actualizarea postarilor. In acest caz, am completat o lista MultiSelectList cu toate etichetele si returneaza ID-urile etichetelor pe care utilizatorul le-a ales. De asemenea, ar trebui sa subliniez ca folosesc aceeasi metoda pentru creare si actualizare, de unde testul de pe linia 5 pentru a vedea daca trebuie sa incarc colectia de etichete curente.
private void ChangeTagsBasedOnMultiSelectList (SampleWebAppDb db, Post post) {var obligatoriuTagIds = UserChosenTags.GetFinalSelectionAsInts (); if (post. escorte veteranilor image.google.bi PostId! = 0) // Aceasta este o actualizare, deci trebuie sa incarcam etichetele db.Entry (post) .Collection (p => p.Tags) .Load (); var newTagsForPost = db.Tags. Unde (x => necesareTagIds.Contains (x.TagId)). ToList (); post.Tags = newTagsForPost; }
Important este ca am incarcat etichete noi din baza de date, astfel incat sa fie urmarite. escorte piata unirii academy-of-art-collegefaculty.us
Concluzie din prima parte
Daca doriti sa actualizati un EF, a furnizat un link de mai multe la multe, atunci:
- Alegeti un capat al unei relatii multi-to-many pentru a actualiza. EF va sorta celalalt capat pentru tine.
- Asigurati-va ca colectia pe care o veti schimba este incarcata, fie punand virtual pe proprietate, folosind .Include () in incarcarea initiala sau utilizand .Load () mai tarziu pentru a obtine colectia.
Nota: .Include () este cea mai performanta dintre cele trei, deoarece inseamna ca datele sunt incarcate in comanda SQL initiala. Celelalte doua, .Load () si virtuale, necesita un al doilea acces SQL. - Asigurati-va ca toate elementele noi, de exemplu Etichetele din exemplul meu, sunt incarcate ca o entitate urmarita.
Acesta este un caz normal, dar in starea deconectata, adica intr-o aplicatie web, care ar putea sa nu fie adevarat (vezi exemplele de mai sus). escorte sex focsani usssabasketball.com - Sunati la EF .SaveChanges () pentru a salva modificarile.
Deoarece ati urmarit entitatile, atunci urmarirea modificarilor EF o va observa si va sorta adaugarea sau eliminarea randurilor din tabelul de legaturi ascunse pentru dvs.
Site web live cu actualizarea relatiilor de la multi la multi
Ca parte a proiectului meu open-source GenericServices, am construit doua exemple de site-uri web. Una dintre ele are o lista simpla de postari pe blog, fiecare avand una sau multe etichete. Postarile si etichetele sunt legate printr-un tabel de la mai multe la multe. Acest site web este live si puteti incerca singur.
- Editati o postare la http://samplemvcwebapp.net/Posts si schimbati etichetele – Nota: daca este accesat de pe desktop, atunci trebuie sa utilizati control-clic pentru a selecta mai multe etichete.
- Puteti vedea, de asemenea, codul care actualizeaza aceasta relatie multi-la-multi prin proiectul open-source SampleMvcWebApp – vedeti codul chiar la sfarsitul clasei DetailPostDto.cs din metoda ChangeTagsBasedOnMultiSelectList. escorte cu video superdlttape.biz
- escorte o
- cache:http://escortero.com/escorte-mature
- porno escorte romania
- escorte odorheiul secuiesc
- escorte bucuresti 2018
- public bet escorte
- escorte mariott
- escorte mues
- escorte de lux.ro
- escorte botosani publi24
- escorte braula
- escorte app
- escorte luhoj
- escorte ion mihalache
- show lesby escorte
- escorte bucuresti mihaela
- escorte tm.com
- escorte braila site:nimfomane.com
- publi24 escorte buzau
- escorte din calarasi
Partea 2: Utilizarea propriei tabele de legaturi pentru relatii intre multe si multe
Exista cazuri in care doriti sa aveti propriul tabel de legaturi, probabil pentru ca doriti sa includeti alte proprietati in tabelul de legaturi. Mai jos este un caz in care mi-am creat pur si simplu propriul tabel de legaturi fara proprietati suplimentare. Dupa cum puteti vedea tabelul PostTagLink are un rand pentru fiecare legatura Tag / Post, la fel ca tabelul ascuns pe care l-a produs EF in prima instanta. Totusi, dupa ce am produs acest lucru, trebuie sa il tinem la curent.
Cursuri Tag, PostTagLink si Post
Asadar, sa realizam acelasi tip de cod Unit Test (conectat) si cod MVC (deconectat) pe care l-am facut in primul exemplu.
Primul raspuns: actualizati relatia mult-la-multi in stare conectata
Cele doua unitati de testare de mai jos arata ca trebuie sa manipulam intrarile tabelului PostTagLink, nu proprietatile de navigare din Post. Dupa ce am salvat modificarile, lista Post-AllocatedTags va reflecta modificarile prin intermediul corectiei relationale a EF efectuata la orice clase urmarite.
[Test] public void Check25UpdatePostToAddTagOk () {folosind (var db = new SampleWebAppDb ()) {// SETUP var badTag = db.Tags.Single (x => x.Slug == “rau”); var firstPost = db. escorte timisaora sprinthealth.com Posts.Primul (); // ATTEMPT db.PostTagLinks.Add (new PostTagLink {InPost = firstPost, HasTag = badTag}); db.SaveChanges (); // VERIFICA primulPost = db.Posts.Include (x => x.AllocatedTags) .Primul (); firstPost.AllocatedTags.Count. escorte ieftine craiova midlandinnovations.com ShouldEqual (3); }} [Test] public void Check26UpdatePostToRemoveTagOk () {folosind (var db = new SampleWebAppDb ()) {// SETUP var firstPost = db.Posts.First (); var postTagLinksToRemove = db.PostTagLinks.First (x => x.PostId == firstPost.PostId); // ATTEMPT db.PostTagLinks.Remove (postTagLinksToRemove); db.SaveChanges (); // VERIFICA primulPost = db.Posts. escorte-sexy.net es.sapr.com Include (x => x.AllocatedTags) .Primul (); prima postare. AllocatedTags.Count.ShouldEqual (1); }}
Cred ca codul vorbeste de la sine, adica adaugati sau eliminati randuri din tabelul PostTagLinks pentru a schimba legaturile.
Al doilea raspuns: actualizati relatia de la multi la multi in stare deconectata
La fel ca primul exemplu atunci cand folosesc MVC, am umplut o lista MultiSelectList cu toate etichetele si returneaza id-urile etichetelor pe care utilizatorul le-a ales. Asadar, acum trebuie sa adaug / elimina randuri din tabelul PostTagLinks. Cu toate acestea, incerc sa nu schimb legaturile care sunt inca necesare, de aceea produc tagLinksToDelete si tagLinksToAdd ca fiind mai eficiente.
private void ChangeTagsBasedOnMultiSelectList (SampleWebAppDb db, Post post) {var obligatoriuTagIds = UserChosenTags.GetFinalSelectionAsInts (); var tagLinksToDelete = db. escorte craiova publi 24 www.applemen.net PostTagLinks.Where (x =>! necesareTagIds.Contains (x.TagId) && x.PostId == PostId) .ToList (); var tagLinksToAdd = necesarTagIds. Unde (x =>! db.PostTagLinks.Any (y => y.TagId == x && y.PostId == PostId)) . escorte tatgoviste cityofneworleans.biz Selectati (z => nou PostTagLink {InPost = post, HasTag = db.Tags.Find (z)}) ToList (.); // Primim corect intrarile PostTagLinks, ceea ce EF are nevoie de tagLinksToDelete.ForEach (x => db.PostTagLinks.Remove (x)); tagLinksToAdd.ForEach (x => db.PostTagLinks.Add (x)); // ************************************************ ******************** // Daca utilizati EF 6, puteti utiliza RemoveRange mai eficient, de ex. //Db. preturi escorte oradea slacky.bluehand.com PostTagLink. RemoveRange (tagLinksToDelete); //db.PostTagLinks.AddRange(tagLinksToAdd); // ************************************************ ********************}
Concluzie din partea a 2-a
Daca aveti propriul tabel de link-uri pentru gestionarea relatiilor dintre multe si multe, trebuie sa aveti
- Adaugati sau eliminati intrarile din tabelul dvs. de legaturi, in cazul meu numit PostTagLink.
- Asigurati-va ca toate elementele noi, de exemplu Eticheta, adaugate in tabelul de legaturi sunt incarcate ca o entitate urmarita.
- Apelati .SaveChanges () la EF pentru a persista modificarile.
Ei bine, asta a durat mai mult decat ma astept sa scriu blogul, dar sper ca ii ajuta pe altii sa inteleaga cu adevarat ce se intampla in relatiile dintre multe si multe dintre EF. Cu siguranta acum ma simt mult mai increzator in aceasta privinta.
Nota suplimentara: Veti vedea ca folosesc comenzile EF direct si nu folosesc un depozit sau un model UnitOfWork atunci cand accesam baza de date. escorte sex anal craiova www.carbondryjapan.com S-ar putea sa doriti sa cititi postarea mea despre „Este util modelul Depozitorului cu Entity Framework?” in ceea ce priveste de ce fac asta.








