Diskuze: Manipulace s databází
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.
Tvůrce
Zobrazeno 28 zpráv z 28.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.
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.
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.
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é...)
V tom se nevyznám. Jsem zvyklý na SQL. V něm by to bylo na 2 řádky.
Co sem zase pleteš velikost? Vždyť to je blbost - zde se toho týkají nějaké 4 řádky...
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í?
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...)
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ě?
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.
OK - a nepomohl by jsi mi s FileTable Template? Děkuji. (Jen to trochu vysvětlit.)
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.
OK - jak bych si tedy měl udělat tabulku v SSMS? (v databázi samozřejmě)
Normálně si jí tam naklikneš Tam není co vysvětlovat.
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í...
Jo to nevím, prý to jde, také mě to zajímá, ještě jsem se k tomu nedostal.
Mohu použít DataSet? Zatím mám jen BindingSource...
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.
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
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.Rows.Add(row);
this.tableScoreTableAdapter.Update(this.dataSet1.TableScore);
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...
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.
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.
Takhle databáze fungují, říká se tomu auto-increment.
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...
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
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í.
Zobrazeno 28 zpráv z 28.