NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!
NOVINKA - Online rekvalifikační kurz Java programátor. Oblíbená a studenty ověřená rekvalifikace - nyní i online.
Avatar
matesax
Tvůrce
Avatar
matesax:5.9.2012 21:12

Dobrý den,
mám 2 problémy s manipulací s databází. První je o něco lehčí - do databáze přidávám (a potřebuji přidávat) data stylem nejnovější nahoru. Ovšem po restartu je to seřazené "správně" (tedy opačně)...

No a druhý problém - mazání řádků. Vždy to prvně vyhodí error, že došlo k narušení:

Narušení souběžného zpracování: Událost DeleteCommand ovlivnila 0 z 1 očekávaných záznamů.

Po dalším zapnutí jdou záznamy již mazat - ovšem co smazání, to pád a hláška, že index mazaného řádku je mimo hranice - řádky se ale naštěstí smažou... :) Děkuji za případnou pomoc.

 
Odpovědět
5.9.2012 21:12
Avatar
Kit
Tvůrce
Avatar
Odpovídá na matesax
Kit:5.9.2012 21:25

Data v databázi seřazena nejsou. Při výstupu si je musíš seřadit tak, jak potřebuješ.

Mazání: Zřejmě data před smazáním čteš a neukončíš čtení. Před smazáním je číst vůbec nemusíš. Bez těch SQL dotazů vařím jen z vody.

Nahoru Odpovědět
5.9.2012 21:25
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
matesax
Tvůrce
Avatar
Odpovídá na Kit
matesax:5.9.2012 21:49

JJ - vím - jen jsem myslel, že defaultně se mi to načte tak, jak to tam dám... JJ - pardon - taková blbost - zapomněl jsem... (neuzavřel jsem spojení). Děkuji.

 
Nahoru Odpovědět
5.9.2012 21:49
Avatar
matesax
Tvůrce
Avatar
Odpovídá na Kit
matesax:5.9.2012 22:05

Tak odvolávám - v tom chyba není. Ukončeno to mám - pro jistotu jsem to nastrkal všude - a nic se nezměnilo...

Dělám lokální databázi ve Form aplikaci. Spojení tedy udržuji pomocí table adaptéru.

private void Form1_Load(object sender, EventArgs e)
{
    this.scoreTableAdapter.Fill(this.database1DataSet.score);
    this.scoreTableAdapter.Connection.Close();

    this.dataGridView1.Columns[0].Visible = false;
    this.dataGridView1.Columns[1].HeaderText = "Jméno";
    this.dataGridView1.Columns[2].HeaderText = "Skóre";
    this.dataGridView1.Columns[3].HeaderText = "Datum";

    this.dataGridView1.Sort(dataGridView1.Columns[3], System.ComponentModel.ListSortDirection.Descending);

    this.dataGridView1.Font = new System.Drawing.Font("Veranda", 16, System.Drawing.FontStyle.Bold);
}

private void button1_Click(object sender, EventArgs e)
{
    var line = database1DataSet.score.NewscoreRow();

    line.name = textBox1.Text;
    line.score = int.Parse(textBox2.Text);
    line.date = DateTime.Now;

    database1DataSet.score.Rows.Add(line);

    this.scoreTableAdapter.Update(this.database1DataSet.score);
}

private void dataGridView1_UserDeletingRow(object sender, DataGridViewRowCancelEventArgs e)
{
    database1DataSet.score.Rows[e.Row.Index].Delete();

    this.scoreTableAdapter.Update(this.database1DataSet.score);
}

Stačí? (podle názvů si snad lze doplnit o jaké proměnné se jedná - ale kdyžtak to pošlu celé...)

 
Nahoru Odpovědět
5.9.2012 22:05
Avatar
Kit
Tvůrce
Avatar
Odpovídá na matesax
Kit:5.9.2012 22:25

V tom se nevyznám. Jsem zvyklý na SQL. V něm by to bylo na 2 řádky.

Nahoru Odpovědět
5.9.2012 22:25
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
matesax
Tvůrce
Avatar
Odpovídá na Kit
matesax:5.9.2012 22:28

Co sem zase pleteš velikost? Vždyť to je blbost - zde se toho týkají nějaké 4 řádky...

 
Nahoru Odpovědět
5.9.2012 22:28
Avatar
David Hartinger
Vlastník
Avatar
Odpovídá na matesax
David Hartinger:5.9.2012 22:30

Dělej s DB přes LINQ, je to modernější způsob.

Nahoru Odpovědět
5.9.2012 22:30
New kid back on the block with a R.I.P
Avatar
Kit
Tvůrce
Avatar
Odpovídá na matesax
Kit:5.9.2012 22:50

O velikost nejde. Jde o to, že kdyby to bylo v SQL, vyznal bych se v tom. Je to v nějakém ORM, který neznám a ani se nehodlám učit. Proto ti v tom nepomohu. Stačí takové vysvětlení?

Nahoru Odpovědět
5.9.2012 22:50
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
matesax
Tvůrce
Avatar
Odpovídá na David Hartinger
matesax:6.9.2012 9:52

Rád bych - ale to proč to mám takto má svůj důvod - ať udělaám cokoliv, vždy když chci tabulku přetáhnout do dbml, tak to zkončí hláškou - něco jako, že daný typ není podporován... (přidal jsem novou databázi, novou tabulku, refreshoval atd...)

 
Nahoru Odpovědět
6.9.2012 9:52
Avatar
David Hartinger
Vlastník
Avatar
Odpovídá na matesax
David Hartinger:6.9.2012 10:45

Jako že chceš LINQ a nejde ti nebo že máš důvod ho nechtít? Databázi navrhuješ v SQL Management Studiu? Mělo by stačit ji správně navrhnout, poté založit novou aplikaci (jakoukoli) a k projektu přidat LINQToSQLClasses. V Server Exploreru si potom nastavit připojení, otevřít DB, označit tabulky a přetáhnout je myší do LINQ projektu. Je to velmi jednoduché.

Co je tam přesně za chybu? Možná tam máš špatné constrainty nebo tak, testoval jsi nějaké dotazy v Management Studio? Založil jsi ji úspěšně?

Nahoru Odpovědět
6.9.2012 10:45
New kid back on the block with a R.I.P
Avatar
David Hartinger
Vlastník
Avatar
Odpovídá na Kit
David Hartinger:6.9.2012 10:49

V C# je několik způsobů pro práci s DB, tento je starší, jedná se o tzv. odpojenou aplikaci, kde objekt symbolizuje tabulku, ta má normálně řádky a sloupce. Insert se např. provede dotazed tabulka.radky­.add(Radek). Nakonec se zavolá update, co danou tabulku v paměti sesynchronizuje s tabulkou v databázi. Myslím, že se zde ani nejedná o ORM.

Přesto ORM v C# doporučuji, používá se tam LINQ, je to docela hezké, i když ne dokonalé, ale co je. LINQ ti umožňuje používat i SQL dotazy nad objekty v databázi, možná by se ti takový způsob i líbil. Stejně tak se můžeš SQL dotazovat i nad obyčejným polem. Nebo naopak můžeš vše řešit jen přes cykly.

Nahoru Odpovědět
6.9.2012 10:49
New kid back on the block with a R.I.P
Avatar
matesax
Tvůrce
Avatar
Odpovídá na David Hartinger
matesax:6.9.2012 17:11

OK - a nepomohl by jsi mi s FileTable Template? Děkuji. (Jen to trochu vysvětlit.)

 
Nahoru Odpovědět
6.9.2012 17:11
Avatar
David Hartinger
Vlastník
Avatar
Odpovídá na matesax
David Hartinger:6.9.2012 18:04

S tím jsem se nikdy moc nekamarádil, můj jediný dosavadní kontakt s databází byl v C# přes LINQ, jak jsem ti popsal výše. Zkusil jsem si i přes Adapter, ale znovu to již vidět nechci. Časem tu něco sepíšu, teď se však věnuji PHP.

Nahoru Odpovědět
6.9.2012 18:04
New kid back on the block with a R.I.P
Avatar
matesax
Tvůrce
Avatar
Odpovídá na David Hartinger
matesax:6.9.2012 18:06

OK - jak bych si tedy měl udělat tabulku v SSMS? (v databázi samozřejmě)

 
Nahoru Odpovědět
6.9.2012 18:06
Avatar
David Hartinger
Vlastník
Avatar
Odpovídá na matesax
David Hartinger:6.9.2012 18:09

Normálně si jí tam naklikneš :) Tam není co vysvětlovat.

Nahoru Odpovědět
6.9.2012 18:09
New kid back on the block with a R.I.P
Avatar
matesax
Tvůrce
Avatar
Odpovídá na David Hartinger
matesax:6.9.2012 18:46

JJ - já se dostal úplně jinam... :)

Jsem schopen se s danou databází spojit - mám ji i v DataClasses, ale mám drobnost - jak ji dostat do složky projektu - prostě tak, aby to fungovalo i na jiných počítačích - fyzicky se k ní dostat nemohu - mám jen kontakt s ní...

 
Nahoru Odpovědět
6.9.2012 18:46
Avatar
David Hartinger
Vlastník
Avatar
Odpovídá na matesax
David Hartinger:6.9.2012 19:12

Jo to nevím, prý to jde, také mě to zajímá, ještě jsem se k tomu nedostal.

Nahoru Odpovědět
6.9.2012 19:12
New kid back on the block with a R.I.P
Avatar
matesax
Tvůrce
Avatar
Odpovídá na David Hartinger
matesax:6.9.2012 19:19

Mohu použít DataSet? Zatím mám jen BindingSource...

 
Nahoru Odpovědět
6.9.2012 19:19
Avatar
matesax
Tvůrce
Avatar
Odpovídá na David Hartinger
matesax:7.9.2012 7:18

Nevíš, co mám dělat se skripty ze MSSMS? Tedy INSERT a SELECT (ovšem ono se mi je ani nedaří vytvořit - postupuji přesně podle správného postupu a vyjde mi script obsahující 2 řádky - "get" a na druhém "go" :) ) - nebo prostě jak tyto metody... Děkuji.

 
Nahoru Odpovědět
7.9.2012 7:18
Avatar
matesax
Tvůrce
Avatar
Odpovídá na David Hartinger
matesax:7.9.2012 13:45

Já teď prostě nevím, s čím mám prácovat. Databinding obsahuje možnost přidat, ale není zde možnost vytvoření řádku pro danou tabulku - tedy co mi chybí (s čím pracovat)? Děkuji

 
Nahoru Odpovědět
7.9.2012 13:45
Avatar
matesax
Tvůrce
Avatar
Odpovídá na Kit
matesax:8.9.2012 18:50

Vzhledem k tomu, že pracuji s lokální databází, spojení vůbec řešit nemusím. (Žádné není...) Přišel jsem si na to sám. Bohužel netuším, jak to vyřešit. Jde o to, že se řídím pomocí sloupce ID (v mé tabulce). No a při vygenerování mám relativně pěkná čísla (-1, -2, -3... - proč je to záporné netuším :) ). Toto je pouze v DataSet - kdy to ještě není přidáno v tabulce. A tady nastává první problém. Nerespektuje to potřebné pořadí výkonu - tedy mám:

this.dataSet1­.TableScore.Row­s.Add(row);
this.tableSco­reTableAdapter­.Update(this.da­taSet1.TableS­core);

Ale prvně se vykoná updatování tabulky a až pak přichází na řadu přidání řádku. Část problému jsem vyřešil tedy tak, že po celou dobu pracuje uživatel pouze s DataSet - a do tabulky se to uloží až při vypnutí programu. (+ přidám tlačítko - něco jako save, či reload...) Jak píši, to vyřešilo pouze problém neexistujícího řádku v tabulce - tedy:

Narušení souběžného zpracování: Událost DeleteCommand ovlivnila 0 z 1 očekávaných záznamů.

Problém 2 je míchání sloupce ID - viz. hoře. Problém je, že netuším, kde dochází ke zkreslení - zda je to tak uloženo v tabulce, či zda je to jen blbě zobrazeno. Každopádně to není jediné, co se růzmě míchá. Prohazují se i jiná data + nelze spoléhát na pořadí výkonu příkazů. Takže netuším, co s tím...

Kód:

private int index;

public Form1()
{
    InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
    this.tableScoreTableAdapter.Fill(this.dataSet1.TableScore);

    this.dataGridView1.Columns[1].HeaderText = "Jméno";
    this.dataGridView1.Columns[2].HeaderText = "Skóre";
    this.dataGridView1.Columns[3].HeaderText = "Datum";

    this.dataGridView1.Sort(dataGridView1.Columns[3], System.ComponentModel.ListSortDirection.Descending);
    this.dataGridView1.Font = new System.Drawing.Font("Veranda", 16, System.Drawing.FontStyle.Bold);
}

private void button1_Click(object sender, EventArgs e)
{
    var row = dataSet1.TableScore.NewTableScoreRow();

    row.name = textBox1.Text;
    row.score = int.Parse(textBox2.Text);
    row.date = DateTime.Now;

    this.dataSet1.TableScore.Rows.Add(row);
}

private void dataGridView1_UserDeletingRow(object sender, DataGridViewRowCancelEventArgs e)
{
    this.dataSet1.TableScore.Rows[index].Delete();
}

private void dataGridView1_SelectionChanged(object sender, EventArgs e)
{
    try
    {
        for (index = 0; index < dataGridView1.RowCount; index++)
            if (dataSet1.TableScore.Rows[index][0].ToString() == dataGridView1.SelectedCells[0].Value.ToString())
                break;
    }
    catch
    {

    }
}

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    this.tableScoreTableAdapter.Update(this.dataSet1.TableScore);
}

Abych byl přesný - problém je v rozdílných datech mezi tabulkou, dataset a tableadaptérem... Takže mě napadá jen napsat si kontakt ručně a vykašlat se na tyto pomůcky... Jinak LINQ to SQL mi nepřijde jako vhodný pro práci s lokální databází - ani to nejde zkombinovat...

 
Nahoru Odpovědět
8.9.2012 18:50
Avatar
Kit
Tvůrce
Avatar
Odpovídá na matesax
Kit:8.9.2012 19:07

Většinou také pracuji s lokální databází (DB4 nebo SQLite), občas se síťovou (MySQL, PostgreSQL). Je fakt, že u lokálních se nemusí řešit přihlašování a v případě primitivních dotazů jsou o dost rychlejší. Na DB4 jsem si v PHP udělal svůj ovladač, takže se to chová jako perzistentní objekt. Podobně jako session, ale globálně pro všechny klienty.

Jenom nevím, proč jsi mi psal ten zbytek. Asi to bylo určeno někomu jinému.

Nahoru Odpovědět
8.9.2012 19:07
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
matesax
Tvůrce
Avatar
matesax:8.9.2012 22:01

Vyřešeno využíváním pouze tableScoreTable­Adapter... Vše je mnohem jednodušší.

 
Nahoru Odpovědět
8.9.2012 22:01
Avatar
matesax
Tvůrce
Avatar
matesax:8.9.2012 22:22

Tak přecijen to má vadu na kráse. Nyní mi vychází v ID pěkná kladná čísla. Bohužel smazané řádky se znovu nepoužívají. Tedy ID sloupec pouze roste. Asi to ničemu nevadí, ale minimálně bych to chtěl resetovat, když budou smazány všechny řádky - šlo by to? Děkuji.

 
Nahoru Odpovědět
8.9.2012 22:22
Avatar
David Hartinger
Vlastník
Avatar
Odpovídá na matesax
David Hartinger:8.9.2012 22:26

Takhle databáze fungují, říká se tomu auto-increment.

Nahoru Odpovědět
8.9.2012 22:26
New kid back on the block with a R.I.P
Avatar
matesax
Tvůrce
Avatar
Odpovídá na David Hartinger
matesax:8.9.2012 22:32

Jo to jo, ale když řádek smažu? Mám na mysli to, že po smazání řádků se nepokračuje od nuly... A že se nepoužívají uvolněná čísla. Takto to zbytečně poroste do výšin a dole bude volno...

 
Nahoru Odpovědět
8.9.2012 22:32
Avatar
David Hartinger
Vlastník
Avatar
Odpovídá na matesax
David Hartinger:8.9.2012 22:35

Výšiny jsou dost vysoké a hledání volného místa by zbytečně komplikovalo zápis. Opravdu je to normální, i zde na devbooku to tak funguje :)

Nahoru Odpovědět
8.9.2012 22:35
New kid back on the block with a R.I.P
Avatar
Kit
Tvůrce
Avatar
Odpovídá na matesax
Kit:8.9.2012 22:36

Resetování autoincrementu je sice u některých databází možné, ale důrazně se to nedoporučuje. Nedovedeš si ani představit, jaké potíže si můžeš způsobit recyklací použitých ID. Proto se to nedělá. Díry v sekvencích ničemu nevadí.

Nahoru Odpovědět
8.9.2012 22:36
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 28 zpráv z 28.