Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

Update DataGrida

[es] :: .NET :: Update DataGrida

[ Pregleda: 2574 | Odgovora: 4 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

hninel
local

Član broj: 9446
Poruke: 34
*.dlp257.bih.net.ba.

Sajt: www..???


Profil

icon Update DataGrida06.06.2005. u 21:24 - pre 228 meseci
Interesuje me kako da ucinim update datagrida nakon snimanja u bazu (dataadapter.update(ds.getchanges()).

Desava se slijdece:

Kada unesem novi red on poveca autoincrement za 1 (redni broj) i to lijepo snimim sa dadapter.Update(...), nakon toga ga recimo izbrisem i sve opet lijepo snimim. Ugasim formu i ponovo je podignem i unesem novi red... Eh tu nastaju problemi...

Kada unesem novi rekord (red), sve je OK, on ga inkrementuje za 1, no kada ga snimi sa daadapter.Update(...) u DataGridu je i dalje onaj broj inkrementovani, te ako sad pokusam da ga obrisem, javlja gresku.

Znaci u ovom trenutku mi trebaju podaci iz baze, jer je ovaj autoincrement broj u bazi drugaciji. Kako da izvrsim update iz baze tj. neki refresh...

Hvala.
 
Odgovor na temu

i_nenad
Nenad Ilic
Beograd

Član broj: 13670
Poruke: 16
195.252.114.*



Profil

icon Re: Update DataGrida07.06.2005. u 09:27 - pre 228 meseci
Hmm, mislim da ce ti ovo resiti problem :

Code:

Dim _ds as dataset = objDS.GetChanges
DA.Update(_ds,"ImeDataTable")
objDS.Merge(_ds)

Posle merge imas u objDS-u nove vrednosti iz baze.

Pozdrav
 
Odgovor na temu

mmix
Miljan Mitrović
Profesorkin muz
Passau, Deutschland

SuperModerator
Član broj: 17944
Poruke: 6041



+4631 Profil

icon Re: Update DataGrida07.06.2005. u 12:06 - pre 228 meseci
Nije to resenje,

DataAdapter ima jednu lepu osobinu da ako stored procedura za insert ili update vrati recordset, DA pretpostavlja da je prvi red tog recordseta unesena tj. izmenjena vrednost reda i to ce naterati DA da promeni vredosti u redu DS-a.

Ovako npr. izgleda stored procedure koja radi po tom principu (ako imas insert trigger nad tabelom, onda iskoristi SCOPE_IDENTITY() umesto @@IDENTITY):

Code:

ALTER PROCEDURE dbo.sp_ImportBatch_Insert
(
    @UserId int,
    @CreatedOn datetime
)
AS
BEGIN
    SET NOCOUNT OFF;
    INSERT INTO ImportBatch(UserId, CreatedOn) VALUES (@UserId, @CreatedOn);
    SELECT ImportBatchId, UserId, CreatedOn FROM ImportBatch WHERE (ImportBatchId = @@IDENTITY);
END


E sad mala "kuvarska" tehnika: U dataset shemi te tabele, postavi Seed i Increment na -1 za identity polje. Ovo je veoma vazno zbog konkurentnosti, ako se vec napuni dataset i onda doda novi red on nece imati vrednost (max(ID)+1) kako se ocekuje (i kako MSSQL radi), nego 1, sto ce ti izazvati key-violation u datasetu ako vec postoji red sa ID=1. Ako su ti Seed i Increment -1, onda ce novi redovi dobijati ID-ove redom -1, -2, etc. i nikad se nece "pobiti" sa realnim IDovima. U trnutku kad Updatujes dataset, gornja stored procedura ce tim redovima dodeliti realne slobodne IDove.
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ć
 
Odgovor na temu

i_nenad
Nenad Ilic
Beograd

Član broj: 13670
Poruke: 16
195.252.114.*



Profil

icon Re: Update DataGrida07.06.2005. u 12:49 - pre 228 meseci
Covek je lepo napisao sintaxu , koju koristi:
dataadapter.update(ds.getchanges())
predpostavljam da koristi generisane comande dataadaptera, a ne stored procedure.
sam po sebi adapter pri komandi prenosi ds ByRef i automatski ga updatuje, ali u ovom slucaju je konkretan problem to sto se updateje ds.Getchanges, sto je novi ds.
znaci jedno resenje je :
dataadapter.update(ds), ako broj slogova koje imas u tebeli nije veliki ili , merge koji sam dao u prvom reply-ju.
Pozdrav
 
Odgovor na temu

mmix
Miljan Mitrović
Profesorkin muz
Passau, Deutschland

SuperModerator
Član broj: 17944
Poruke: 6041



+4631 Profil

icon Re: Update DataGrida07.06.2005. u 14:36 - pre 228 meseci
Citat:
i_nenad: Covek je lepo napisao sintaxu , koju koristi:
dataadapter.update(ds.getchanges())
predpostavljam da koristi generisane comande dataadaptera, a ne stored procedure.
...
znaci jedno resenje je :
dataadapter.update(ds), ako broj slogova koje imas u tebeli nije veliki ili , merge koji sam dao u prvom reply-ju.
Pozdrav


Hmm, ajd da probam da obrazlozim zasto ovo ne valja.

1. Cak i kad se automatski generisu komande kao sto pretpostavljas, i dalje je po defaultu ukljucena opcija "Refresh dataset", koja ce napraviti SQL komandu sa sledecim CommandText-om:
Code:

UPDATE ImportBatch SET UserId = @UserId, CreatedOn = @CreatedOn WHERE (ImportBatchId = @Original_ImportBatchId); 
SELECT ImportBatchId, UserId, CreatedOn FROM ImportBatch WHERE (ImportBatchId = @ImportBatchId)

sto se svodi na stored proceduru koju sam napisao gore. Ako nema SELECT u komandi, ne postoji automaski nacin da se osvezi dataset sa generisanim vrednostima. To je prvo sto mora da se proveri, bez toga je ostatak ovog topica nevazan.

2. ds.GetChanges proizvede kopije redova koji su dodati/promenjeni/obrisani. Ti redovi vise nemaju nikakve veze sa originalnim redovima. Kad se ovaj dataset posalje adapteru ti "novi" redovi dobiju nove IDove ili ostanu isti (ako nema SELECT dela iz tacke 1.), nazovimo ovaj dataset DSCH

3. Kad radis Merge, jedini nacin da dataset zakljuci koji redovi su novi a koji izmenjeni je PrimaryKey. I sad se javljaju dve opcije (od kojih nijedna ne valja):

3.1 (bez SELECTA u komandi): ID polje je ostalo isto, dataset ce ostale vredosti u redu zameniti sa onima iz DSCH, tj, nece uraditi nista posto dataadapter nije menjao DSCH jer se iz komande/stored procedure nije nista vratilo.
3.2 (sa SELECT): ID polje ce dobiti novu realnu vrednost u DSCH. ds ce pretraziti svoj primary key i videce da ne postoji red sa tim ID-om i zakljucice da je taj red iz DSCH ustvari NOVI RED i dodace ga umesto da stari zameni novim. Kao posledica ovoga svi dodati redovi u ds ce se duplirati samo sa drugim ID-ovima. Dalje, svi redovi koji su bili iskopirani sa GetChanges ce i dalje ostati u statusu "Added" i ako ponovo pozoves GetChanges,Update bice ponovo dodati u bazu.


Bottom line, ne postoji razlog da se koristi dataadapter.update(ds.getchanges()) sem kad se dataset salje preko webservisa ili u remoting pa da se smanji pritisak na bandwitdh (a u tom slucaju posle svakog merge-a mora da se radi ciscenje duplikata).
U WinForms je UVEK bolje koristiti dataadapter.update(ds), posto ce dataadapter pre poziva komandi uraditi pretrazivanje dataset-a isto kao sto ce to uraditi ds.GetChanges() samo sto ce:

a) biti brze, posto nece praviti kopije redova
b) biti efikasnije, posto ce SELECT u komandi automatski promeniti red u originalnom datasetu te nema potrebe za merge-om.

Broj redova nema veze sa ovim, ako ukupno ima milion redova u datasetu, i dataadapter i ds.GetChanges moraju da prodju kroz isti proces da bi odredili koji treba da se posalju bazi (tj koji treba da se iskopiraju u DSCH).

PS. Sad vidim da nisam eksplicitno naveo da uz moj primer mora da se koristi dataadapter.update(ds), izvinjavam se za tu omasku.

PS> Ako mi i dalje ne verujes probaj sledeci kod (dataset je zakacen za poruku):

Code:

    class Class1
    {

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main(string[] args)
        {
            DatasetX dsx = new DatasetX();
            dsx.tabela.AddtabelaRow("novi red 1");
            dsx.tabela.AddtabelaRow("novi red 2");
            Console.WriteLine("Pre getchanges/update/merge");
            PrintTable(dsx.tabela);
            DatasetX dsch = (DatasetX)dsx.GetChanges();
            SimulateDataAdapter(dsch, 25);
            dsx.Merge(dsch);
            Console.WriteLine("Post merge");
            PrintTable(dsx.tabela);
            dsch = (DatasetX)dsx.GetChanges();
            SimulateDataAdapter(dsch, 35);
            dsx.Merge(dsch);
            Console.WriteLine("Post second merge");
            PrintTable(dsx.tabela);
            Console.ReadLine();
        }

        static void PrintTable(DatasetX.tabelaDataTable tbl)
        {
            foreach (DatasetX.tabelaRow _row in tbl.Rows)
            {
                Console.Write("{0,3} : {1}\n", _row.ID, _row.polje);
            }
        }

        static void SimulateDataAdapter(DatasetX dsch, int start)
        {
            int xx = start; // recimo da je start prvi sledeci slobodni u bazi
            foreach (DatasetX.tabelaRow _row in dsch.tabela.Rows)
            {
                _row.ID = xx++;
            }
            dsch.AcceptChanges();
        }
    }


ovo je izlaz koji ces dobiti:

Code:

Pre getchanges/update/merge
 -1 : novi red 1
 -2 : novi red 2
Post merge
 -1 : novi red 1
 -2 : novi red 2
 25 : novi red 1
 26 : novi red 2
Post second merge
 -1 : novi red 1
 -2 : novi red 2
 25 : novi red 1
 26 : novi red 2
 35 : novi red 1
 36 : novi red 2


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ć
Prikačeni fajlovi
 
Odgovor na temu

[es] :: .NET :: Update DataGrida

[ Pregleda: 2574 | Odgovora: 4 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.