• 42 odgovora
  • 12.201 pregleda
ADO.NET i izdavanje racuna 10.01.2009. u 21:07 · pre 216 meseci #1
U jednoj maloj aplikaciji koju radim, postoji potreba za idavanjem računa.

Zbog samog načina na koji ADO.NET funkcioniše (disconnected model), u trenutku kada bih trebao da odštampam račun, ja ne znam ID koji će mu biti dodeljen u bazi.

Na koji način se može rešiti ovaj i slični problemi koje ADO.NET zbog svog načina pristupu podacima nosi sa sobom?

Unapred hvala na odgovorima.
Re: ADO.NET i izdavanje racuna 11.01.2009. u 12:14 · pre 216 meseci #3
Evo da objasnim logiku koju koristim.

Za izdavanje računa koristim tri tabele, Racuni (PK idRacuna), Stavke(idStavke) i Artikli(PK(idRacuna,idStavke)).

Prilikom otvaranja forme kreiram objekat tipa RacuniRow u koji upisujem datum, vreme i druge podatke, i koji snimam u DataSet tabelu Racuni. Kada dodajem stavke u tabelu prosledjujem ArtiklRow i RacunRow objekat pored drugih podataka vezanih za datu stavku. Sve se ovo korektno snimi u DataSet bez grešaka. -> klasičan scenario izdavanja računa

Interesuje me postoji li način da se zaobiđe upisivanje u bazu pre kreiranja izveštaja (dakle sve podatka koji su mi potrebni da pročitam iz DataSeta a ne iz baze) pošto bi na taj način mogao dodatno ubrzati aplikaciju (smatram da je tako, ako grešim ispravite me)? Ukoliko gornji redosled događaja nije izvodljiv, postoji li način da mi odmah nakon upisa u tabelu Racun iz DataSet.Racun tabele bude vraćen idRacuna pod kojim je novi red snimljen?
Re: ADO.NET i izdavanje racuna 11.01.2009. u 13:05 · pre 216 meseci #4
moj prijedlog.

stavi jedno pomoćno polje u bazu.


na pokretanje forme neka ti se izgenerira jedan broj koji će se sastojat od -> id_korisnika ili id_kase.
i možeš dodat vrijeme(sat, minuta i sekunda).

i prilikom spremanja učitaš max. broj u bazi dodaš 1 i spremiš.
ako u međuvremenu netko spremi s tim brojem, napraviš u proceduri da opet proba i tako dugo se vrti dok ne upiše.
ovo radiš preko procedure i nakon toga učitaš račun(broj i ostalo gdje je pomoćni broj jednak na formi).

to ti je cijela mudrost.
Re: ADO.NET i izdavanje racuna 11.01.2009. u 13:51 · pre 216 meseci #5
Hvala Marko, tako cu i uraditi. Mislio sam da u samom frameworku postoji resenje ovog problema.
Re: ADO.NET i izdavanje racuna 11.01.2009. u 15:00 · pre 216 meseci #6
a drugi prijedlog je.

kad ti se forma otvori da spremiš broj računa, a onda radiš update sa forme.
mana ovog je da ako odustaneš, onda ostane rupa, a tog ne smije biti.
Re: ADO.NET i izdavanje racuna 11.01.2009. u 16:35 · pre 216 meseci #7
Implementiraću malo modifikovanu verziju tvog prvog predloga. Nadam se da neće to smanjiti brzinu izvršavanja aplikacije.
Re: ADO.NET i izdavanje racuna 11.01.2009. u 17:17 · pre 216 meseci #8
Sad tek vidim ovu temu.

Sto se uopste maltertirate sa time, ako je adapter dobro napravljen dobices posle update-a nazad nove ID-eve, a samu dataset schemu (pretpostavljam da ti je ID polje autoinkrement) namestis da ID polja budu seed -1 increment -1 da se osiguras da novi redovi nikad ne preklapaju i sve ti je reseno samo.

fora sa MAX+1 i optimistickim lockingom je nepotrebno spora a verovatno i neizvodljiva ako je ID autoincrement (u prevodu ako sam SQL server radi to sto ti hoces, tj. max+1, s tim sto SQL server zna koji je max bez da skenira celu tabelu)
Potpis
Sloba je za 12 godina promenio antropološki kod srpskog naroda. On je od jednog
naroda koji je bio veseo, pomalo površan, od jednog naroda koji je bio znatiželjan, koji
je voleo da vidi, da putuje, da upozna,
od naroda koji je bio kosmopolitski napravio narod koji je namršten, mrzovoljan,
sumnjicav, zaplašen, narod koji se stalno nešto žali, kome je stalno neko kriv - Z.Đinđić
Re: ADO.NET i izdavanje racuna 11.01.2009. u 20:49 · pre 216 meseci #9
Upravo te vrednosti IDieva su mi i potrebne, a ne mogu da pronađem u dokumentaciji kako da ih pokupim.

Pri dodavanju novih stavki koristim metod kome prosleđujem "roditeljske" redove iz tabela Racun i Artikli, kako su seed i increment ID polja setovani od strane .Neta (koristim strongly typed DataSet) sama rutina se i pobrine da redovi u DataSet.Stavke budu referencirani na odgovarajuće redove u tabelama Racuni i Artikli.

Pogledaću još dokumentaciju, pa ću javiti šta sam uspeo da uradim.
Re: ADO.NET i izdavanje racuna 11.01.2009. u 21:09 · pre 216 meseci #10
I to si uradio kako treba (referenciranje objektima dataset u pozadini "prepeva" u referenciranje ID-em), ono sto tebi treba je dobro konfigurisan DataAdapter. Imas li ga? Kako uopste upisujes dataset u bazu? DataAdapter ima 4 CRUD komande select, insert, update i delete. AKo insert/update na kraju svog posla urade select koji vrati upravo unet/updateovan red onda ce dataadapter automatski updateovati sam dataset iz kojeg je potekla izmena/nov red. Tako se radi. Insert komanda npr treba da bude:

Code:

insert into Tabela (p1, p2) values (@p1, @p2);
select TabelaID, p1, p2 from Tabela where TabelaID = SCOPE_IDENTITY();


Potpis
Sloba je za 12 godina promenio antropološki kod srpskog naroda. On je od jednog
naroda koji je bio veseo, pomalo površan, od jednog naroda koji je bio znatiželjan, koji
je voleo da vidi, da putuje, da upozna,
od naroda koji je bio kosmopolitski napravio narod koji je namršten, mrzovoljan,
sumnjicav, zaplašen, narod koji se stalno nešto žali, kome je stalno neko kriv - Z.Đinđić
Re: ADO.NET i izdavanje racuna 11.01.2009. u 21:48 · pre 216 meseci #11
Vrednosti iz neke tabele u DataSetu upisujem pozivanjem tableAdapter.Update() metoda. U principu izradu DataSeta radim u designeru, tako da i Update metode TableAdaptera radim kroz designerov wizard.
Ukoliko imas link ka dokumentaciji o ovoj temi verujem da bi mi prilicno koristio.

Re: ADO.NET i izdavanje racuna 12.01.2009. u 18:06 · pre 216 meseci #12
A ako više korisnika koristi programčić pa onda se desi da posle štampanja računa a pre snimanja računa u bazu iz bilo kog razloga padne ili program ili sistem a neznajući to drugi korisnik uradi svoj račun dobićeš dva izdata računa sa istim brojem. mislim da je bolje pre štampanja upisati račun u bazu a potom korišćenjem output parametara u SP i @@identity dobiti ID (koji mora biti autoid tj increment 1).
Re: ADO.NET i izdavanje racuna 12.01.2009. u 20:23 · pre 216 meseci #13
Pa logika bi i isla tako.

Izvrsiti update baze koji bi vratio idRacuna u bazi.

Posto koristim DataAdapter.Update() metod za snimanje redova u bazu (zbog toga sto detektuje sve promene u okviru DataSeta i izvrsava potrebne Insert, Update i Delete queryje), da li cu u ovom slucaju morati da koristim DataAdapter.Insert() tako sto cu za svaki novi red u tabeli krekirati njegov objekat, dodati ga postojecoj DataSet tabeli i proslediti ga kao parametar DataAdapter.Insert() metodu?

[Ovu poruku je menjao perun85 dana 12.01.2009. u 21:46 GMT+1]
Re: ADO.NET i izdavanje racuna 13.01.2009. u 14:32 · pre 216 meseci #14
Ja koristim sledeći sistem:
- Formiram tabelu u kojoj čuvam prvi sledeći broj računa.
- Pre štampe računa upisujem ga u bazu (do tada, račun se može i poništiti, menjati, brisati i ...) ali čim se štampa onda je konačan i mora se uneti u bazu
- Započnem transakciju, zaključam tabelu u kojoj čuvam sledeći broj računa, uzimam ga, upisujem u tabelu u kojoj čuvam račune, uvećam broj računa za jedan, upišem u tabelu sledećeg broja računa otključavam tu tabelu, završim transakciju.

Time postižem da niko ne može uneti dva ista broja računa, ne može se napraviti preskok broja računa, a u višekorisničkom radu zaključavanje tabele je veoma kratko i što je i po meni veoma bitno mogu da koristim bilo kakvu funkciju za promenu broja računa. Banalan primer je štampanje čekova čiji brojevi se menjaju po nekom algoritmu a ne uvećavaju se za jedan. Više puta sam pisao o tome i uvek se ponovi isto pitanje, a da ne pičam o sistemu koji traži najveći broj pa ga uvećava za jedan (veoma često u temama o access-u).

I, naravno, nisam ja izmislio ovaj sistem. Njega koriste svi oni koji koriste baze podataka koje nemaju tip podataka sa automatskim uvećanjem (AutoIncrement), a verovali ili ne ima i takvih baza podataka koje veoma lepo rade i bez toga.
Re: ADO.NET i izdavanje racuna 13.01.2009. u 16:56 · pre 216 meseci #15
Nikad mi nije bila jasna ta apsolutna opsesija kontinualnoscu ID-eva. Zasto je toliki greh preskociti broj da zbog toga pribegavate simuliranju ID-eva koje je prevazidjeno jos pre desetak godina? Najgore je sto se nista ne postize jer ste samo preneli referential integrity sa RDBMS na aplikativni nivo, svako sa SQL klijentom i loginom moze upropastiti celokupan integritet kljuceva tako sto ce da zaobidje mehanizme uspostavljene na aplikativnom nivou. I naravno da ima baza koje rade bez autoincrementa, na kraju krajeva mozes podatke da drzis i na busenim karticama.

Da ne pominjem probleme sa skalabilnoscu baze. ID je ID, njegova osnovna svrha nije nosenje korisnickih informacija vec uspostavljanje jedinstvenog nekompozitnog kljuca za optimalniju konstrukciju 3NF tabela i relacija. Kad koristis korisnicki definisan ID kao kljuc onda efektivno zakljucavas shemu baze na taj poslovni model i svaka sledeca izmena postaje nocna mora. Ako vec moras da imas neprekidnu i sekvencijalnu kontrolu nad nekim podatkom onda se to stavlja u zasebno polje cija dodela se kontrolise kroz pomenuti mehanizam sa lockovima na counter tabelu. To nece zastititi od manuelne izmene u bazi ali bar nece dovesti do referencijalnog raspada iste zato sto je neko resio da ubuduce broj racuna bude xxx/yy umesto xxxxx.
Potpis
Sloba je za 12 godina promenio antropološki kod srpskog naroda. On je od jednog
naroda koji je bio veseo, pomalo površan, od jednog naroda koji je bio znatiželjan, koji
je voleo da vidi, da putuje, da upozna,
od naroda koji je bio kosmopolitski napravio narod koji je namršten, mrzovoljan,
sumnjicav, zaplašen, narod koji se stalno nešto žali, kome je stalno neko kriv - Z.Đinđić
Re: ADO.NET i izdavanje racuna 13.01.2009. u 21:44 · pre 216 meseci #16
Scenario za izdavanje racuna koji nameravam da primenim u aplikaciji je sledeci:

- pri pokretanju forme za kreiranje racuna automatski se unosi novi red u tabelu Racuni i vraca se njegov ID

- dodavanje DataSet tabeli Racuni novog reda

- kreiranje objekta pomenutog Racuna

- kreiranje objekta artikla koji se unosi u racun

- pri dodavanju svakog artikla u DataSet tabelu Stavke prosledjivanje objekta reda racuna, objekta artikla, ukupne cene i sl.

- povecavanje ukupne vrednosti kolone ukupanIznos reda u DataSet tabeli Racun

- ukoliko se kupac predomisli u vezi nekog artikla brise se iz DataSet Stavke njegov unos i ukupanIznos racuna
se smanjuje

- ukoliko odustane od celokupne kupovine brise se red tog racuna iz baze i svenjegove stavke u DataSet

- pre stampanja snimanje u bazu svih stavki ovog racuna i ukupnog iznosa, nakon cega sledi sama stampa izvestaja

Kako ja ovo posmatram bez obzira koliko korisnika da koristi sistem, ni u jednom trenutku ne bi trebalo da dodje do greske kao sto je izdavanje dva racuna sa istim IDijem. U ovom slucaju sasvim je svejedno da li ce u bazi radni brojevi racuna ici u savrsenom rastucem nizu, jedino ako to nije specijalan zahtev klijenta, jer referencijalni integritet nije narusen, tako da se slazem sa mmixom.


Citat:
zaključam tabelu u kojoj čuvam sledeći broj računa


ADO.NET nema native podrsku za pessimistic concurrency. Koliko sam video na netu, postoje samo odredjeni workaround nacini da se to izvede.
Re: ADO.NET i izdavanje racuna 13.01.2009. u 22:45 · pre 216 meseci #17
Citat:
perun85: Scenario za izdavanje racuna koji nameravam da primenim u aplikaciji je sledeci:

Kako ja ovo posmatram bez obzira koliko korisnika da koristi sistem, ni u jednom trenutku ne bi trebalo da dodje do greske kao sto je izdavanje dva racuna sa istim IDijem. U ovom slucaju sasvim je svejedno da li ce u bazi radni brojevi racuna ici u savrsenom rastucem nizu, jedino ako to nije specijalan zahtev klijenta, jer referencijalni integritet nije narusen, tako da se slazem sa mmixom.

ADO.NET nema native podrsku za pessimistic concurrency. Koliko sam video na netu, postoje samo odredjeni workaround nacini da se to izvede.


Vidiš, ID i nije broj računa , broj čeka, broj transakcije, ili broj ... ID i dalje služi za vezu među tabelama i može da bude i čak i autoincrement, nebitno, sve dok je jedinstven, ali nekada brojevi koji se ispisuju na dokumentima moraju da slede neki algoritam. Već sam naveo broj čeka. Odete u banku, poručite čekove, a ono na njima neki brojevi bez veze i reda. Kako onda voditi evidenciju? Nekada ti brojevi i ne moraju da budu brojevi već bilo koja kombinacija alfanumerika formirana po nekom određenom pravilu

Citat:
mmix: Nikad mi nije bila jasna ta apsolutna opsesija kontinualnoscu ID-eva. Zasto je toliki greh preskociti broj da zbog toga pribegavate simuliranju ID-eva koje je prevazidjeno jos pre desetak godina? Najgore je sto se nista ne postize jer ste samo preneli referential integrity sa RDBMS na aplikativni nivo, svako sa SQL klijentom i loginom moze upropastiti celokupan integritet kljuceva tako sto ce da zaobidje mehanizme uspostavljene na aplikativnom nivou. I naravno da ima baza koje rade bez autoincrementa, na kraju krajeva mozes podatke da drzis i na busenim karticama.

Da ne pominjem probleme sa skalabilnoscu baze. ID je ID, njegova osnovna svrha nije nosenje korisnickih informacija vec uspostavljanje jedinstvenog nekompozitnog kljuca za optimalniju konstrukciju 3NF tabela i relacija. Kad koristis korisnicki definisan ID kao kljuc onda efektivno zakljucavas shemu baze na taj poslovni model i svaka sledeca izmena postaje nocna mora. Ako vec moras da imas neprekidnu i sekvencijalnu kontrolu nad nekim podatkom onda se to stavlja u zasebno polje cija dodela se kontrolise kroz pomenuti mehanizam sa lockovima na counter tabelu. To nece zastititi od manuelne izmene u bazi ali bar nece dovesti do referencijalnog raspada iste zato sto je neko resio da ubuduce broj racuna bude xxx/yy umesto xxxxx.


Čini mi se da baš i ne razumeš to što pišeš jer pišeš o stvarima o kojima niko nije ni pričao. Ta "opsesija" je nekada srž problema i mora se ispoštovati. Dobro si rekao da osnovna svrha ID nije nošenje korisničkih informacija pa ze za takve stvari i ne koristi i niko nije rekao da mora da postoji kontinualnost ID-jeva, ali zato mora da postoji kontinualnost brojeva računa u fiskalnoj kasi, kontinualnost brojeva serije čekova koji se izdaju, kontinualnost serijskig brojeva karata za neki koncert, voz, ringišpil, ... A ako znaš da napišeš funkciju onda možeš na kartama da štampaš broj reda i sedišta, ili broj vagona, kupea i sedišta, i da širimo dalje. Postoji veoma mnogo prilika kada je taj tvoj ID nekoristan za sve osim za povezivanje tabela
Re: ADO.NET i izdavanje racuna 13.01.2009. u 23:30 · pre 216 meseci #18
Ako sam dobro razumeo Perune cini mi se da malo komplikuješ stvari. Zašto bi odmah na startu formiranja tražio ID buduceg racuna kada se može desiti da taj racun ni ne bude formiran. Moja praksa je da
1. Najpre formiram ceo racun(ukljucujuci i stavke racuna)
2. Zatim snimim racun(u tu svrhu koristim SP koja mi kao output parametar vrati ID preko @@identyti)
3. Kada imam ID stampam racun
4. I ne brisem jednom snimljeni racun nego ga storniram.
5. Koristim i transakcije da se ne desi da nesto snimi a nesto ne.


Re: ADO.NET i izdavanje racuna 13.01.2009. u 23:44 · pre 216 meseci #19
A što za ID ne koristite GUID, a za "govoreće" šifre (broj računa) drugo polje tipa string/int?
Zar nije malo cim kada imate parent/child relacije: prvo se snimi parent, pa dobijete njegov id pa onda u svim childovima parent_id zamenite sa tim novim id-em?
A kao što mmx reče, šta kada se promeni poslovna logika pa broj računa nije više u xxx nego u xxx/yy formatu. Lakše je izmeniti podatke u jednoj nego u n tabela u bazi.
Zatim, zar nije jako loše rešenje koristiti auto increment polja u bazi?
Šta kad treba izvršiti import podataka?

just my 2 cents
Potpis
77 77 77 2E 65 73 6E 69 70 73 2E 63 6F 6D
Re: ADO.NET i izdavanje racuna 14.01.2009. u 00:33 · pre 216 meseci #20
Astek, ne buduceg racuna nego onog za koga se trenutrno unose stavke u formi.
Odgovori
Prijavite se da biste odgovorili u ovoj temi.PrijavaRegistracija

Premeštanje teme