Cel mai bun mod de a modela relațiile Multe-la-Unu în NHibernate atunci când se ocupă de un DB Legacy?

Atenție - Sunt foarte nou la NHibernate. Știu că această întrebare pare a fi simplă - și sunt sigur că există un răspuns simplu, dar mi-am rotit roțile de ceva timp pe asta. Am de-a face cu o moștenire db care într-adevăr nu poate fi modificată structural. Am un tabel care detaliază planurile de plată acceptate de un client. Fiecare plan de plată are un ID care trimite înapoi la o tabelă de referință pentru a obține termenii, condițiile, etc. În modelul meu de obiecte, am o clasă AcceptedPlan și o clasă Plan. Inițial, am folosit o relație multi-la-unu din tabelul de detaliu înapoi la tabelul de referință pentru a modela această relație în NHibernate. De asemenea, am creat o relație one-to-many mergând în direcția opusă de la clasa Plan până la clasa AcceptedPlan. A fost bine în timp ce citiam doar date. Aș putea merge la obiectul Planului meu, proprietate a clasei mele AcceptedPlan, pentru a citi detaliile planului. Problema mea a apărut când a trebuit să încep să introduc noi rânduri în tabelul cu detalii. Din lectura mea, se pare că singura modalitate de a crea un nou obiect copil este să o adăugați la obiectul părinte și apoi să salvați sesiunea. Dar nu vreau să creez un nou obiect al planului părinte de fiecare dată când vreau să creez un nou record detaliat. Acest lucru pare a fi o cheltuială inutilă. Știe cineva dacă mă gândesc la asta în mod greșit?

0
fr hi bn

6 răspunsuri

Cred că problema pe care o aveți aici este că obiectul AcceptedOffer conține un obiect Plan și apoi obiectul dvs. Plan pare să conțină o colecție AcceptedOffers care conține obiecte AcceptedOffer. Același lucru cu clienții. Faptul că obiectele sunt un copil unul altuia este ceea ce cauzează problema dvs., cred.

De asemenea, ceea ce face complexul dvs. AcceptedOffer este că are două responsabilități: indică ofertele incluse într-un plan, indică acceptarea de către un client. Aceasta încalcă principiul unic responsabilitate.

Este posibil să trebuiască să faceți o diferențiere între o Ofertă care face parte dintr-un Plan și o Ofertă acceptată de clienți. Deci, iată ce voi face:

  1. Creați un obiect Ofertă separată care nu are o stare, de exemplu, nu are un client și nu are o stare - are doar un OfferId și Planul de care aparține ca atribute.
  2. Modificați obiectul Plan pentru a avea o colecție de Oferte (nu trebuie să fi acceptat oferta în contextul său).
  3. În final, modificați obiectul AcceptedOffer astfel încât acesta să conțină o Ofertă, Clientul și o Stare. Clientul rămâne același.

Cred că acest lucru va dezlega suficient mapările dvs. NHibernate și problemele de economisire a obiectelor. :)

0
adăugat

Un sfat care poate (sau nu poate fi) de ajutor în NHibernate: puteți să vă cartografiați obiectele cu Vizualizări, de parcă vizualizarea a fost o tabelă. Doar specificați numele de vizualizare ca nume de tabel; atâta timp cât toate câmpurile NOT NULL sunt incluse în vizualizare, iar maparea va funcționa bine.

0
adăugat

Nu știu dacă acest lucru este posibil deoarece experiența mea NHibernate este limitată, dar ați putea crea o clasă BaseDetail care are doar proprietățile detaliilor pe măsură ce acestea sunt direcționate direct spre tabelul Detaliu.

Apoi creați o clasă a doua care moștenește din clasa BaseDetail care are obiectul Planul părinte suplimentar, astfel încât să puteți crea o clasă BaseDetail atunci când doriți să creați doar un rând detaliat și să îl atribuiți PlanId, dar dacă trebuie să completați o detaliu detaliat înregistrați cu obiectul Planul părinte puteți folosi clasa Delimitare moștenită.

Nu știu dacă asta are sens, dar spune-mi și voi clarifica mai departe.

0
adăugat

Abordarea pe care o iau pentru a modela acest lucru este după cum urmează:

Customer object contains an ICollection PaymentPlans which represent the plans that customer has accepted.

Planul de plăți către client va fi cartografiat folosind un sac care utilizează tabelul cu detalii pentru a stabili ce ID de client a fost mapat la care se plătește Plata. Folosind cascada all-delete-orphan, în cazul în care clientul a fost șters, atât intrările de la detalii, cât și plățile de plată pe care le dețin clientul vor fi șterse.

Obiectul PaymentPlan conține un obiect PlanTerms care reprezintă termenii planului de plată.

PlanTerms-urile ar fi mapate într-un Plăci de Plăți utilizând o actualizare de salvare-salvare de tip cascadă de tip multi-to-one, care ar introduce doar o referință la obiectul PlanTerms relevant în Formularul de Plăți.

Folosind acest model, ați putea să creați PlanTerms independent și atunci când adăugați un nou PayPlan unui client, creați un nou obiect PaymentPlan care trece prin obiectul PlanTerms relevant și apoi îl adăugați la colecția de pe clientul respectiv. În cele din urmă, ați salva clientul și lăsați cascada nhibernate operațiunea de salvare.

Veți ajunge la un obiect al clientului, la un obiect PaymentPlan și la un obiect PlanTerms cu clientul (tabelul clientului) care deține exemple de plăți de plată (tabelul cu detalii), care aderă la toate PlanTerms specifice (tabelul de plan).

Am câteva exemple mai concrete ale sintaxei de mapare, dacă este necesar, dar probabil că este bine să lucrați cu modelul dvs. și nu am suficiente informații despre tabelele bazei de date pentru a furniza exemple specifice.

0
adăugat

M-aș îndepărta de obiectul copil care conține părintele lor logic, poate deveni foarte dezordonat și foarte recursiv destul de repede când faci asta. Aș arunca o privire la modul în care intenționați să utilizați modelul de domeniu înainte să faceți astfel de lucruri. Puteți să aveți în continuare cu ușurință referințele ID din tabele și să le lăsați neimprimate.

Iată două exemple de mapări care ar putea să vă îndrepte în direcția corectă, am avut de a adlib nume de tabele etc, dar ar putea ajuta eventual. Probabil aș sugera, de asemenea, să scriu StatusId la o enumerare.

Acordați atenție modului în care geanta etalează cu ușurință tabelul cu detalii într-o colecție.

<?xml version="1.0" encoding="utf-8" ?>

    
        
            
            
        

        
          
          
        

  



<?xml version="1.0" encoding="utf-8" ?>

    
        
            
            
        

        
        
        

        
            
        

  

0
adăugat

Nu am văzut diagrama bazei de date în timp ce scriu.

<?xml version="1.0" encoding="utf-8" ?>

    
        
            
            
        

        
            
            
        

  



<?xml version="1.0" encoding="utf-8" ?>

    
        
            
            
        

        
            
        

  

Ar trebui probabil să faci truc (am făcut doar cartografiere de exemplu pentru colecții, va trebui să adăugați alte proprietăți).

0
adăugat