Základy programování 4 - C# 7. cvičení Radek Janoštík Univerzita Palackého v Olomouci 26.3.2017 Radek Janoštík (Univerzita Palackého v Olomouci) Základy programování 4 - C# 26.3.2017 1 / 14
Reakce na úkoly (1/2) 2x stejný string s dotazem SqlCommand add = new SqlCommand("INSERT INTO students (OsCislo, Jmeno, Prijmeni, UserNam add.parameters.add(new SqlParameter("OsCislo", "R007")); add.parameters.add(new SqlParameter("Jmeno", "James")); add.parameters.add(new SqlParameter("Prijmeni", "Bond")); add.parameters.add(new SqlParameter("UserName", "JB7")); add.parameters.add(new SqlParameter("Rocnik", 12)); add.parameters.add(new SqlParameter("OborKomb", "APLINF")); int aff = add.executenonquery(); Console.WriteLine($"Affected after adding: {aff"); SqlCommand add2 = new SqlCommand("INSERT INTO students (OsCislo, Jmeno, Prijmeni, UserNa add2.parameters.add(new SqlParameter("OsCislo", "R17002")); add2.parameters.add(new SqlParameter("Jmeno", "Karel")); add2.parameters.add(new SqlParameter("Prijmeni", "Řízek")); add2.parameters.add(new SqlParameter("UserName", "řízkka02")); add2.parameters.add(new SqlParameter("Rocnik", 3)); add2.parameters.add(new SqlParameter("OborKomb", "APLINF")); Kdy tedy použít paramery a kdy je nemusíme použít? Radek Janoštík (Univerzita Palackého v Olomouci) Základy programování 4 - C# 26.3.2017 2 / 14
Reakce na úkoly (2/2) Nepoužití metod Limitace výstupu přímo v kódu, nikoliv v SQL var i = 0; var command = new SqlCommand("SELECT DISTINCT Jmeno, Prijmeni FROM students ORDER BY Prijmeni ASC;", conn); using (var dr = command.executereader()) { while (dr.read()) { if (i >= 4 && i < 15) Console.WriteLine($"{dr[0], {dr[1]"); i++; vs. SqlCommand ukol1 = new SqlCommand("SELECT DISTINCT Jmeno, Prijmeni FROM students ORDER BY Prijmeni OFFSET 5 ROWS FETCH NEXT 10 ROWS ONLY;", conn); Radek Janoštík (Univerzita Palackého v Olomouci) Základy programování 4 - C# 26.3.2017 3 / 14
Object-relational mapping (ORM) Automatické mapovení objektů do relační databáze Náš pohled transparentní práce s databází pomocí objektů Dva přístupy CodeFirst Databáze se generuje z programu DatabaseFirst Programový kód se generuje dle struktury DB Zde ukážeme pouze CodeFirst Radek Janoštík (Univerzita Palackého v Olomouci) Základy programování 4 - C# 26.3.2017 4 / 14
Entity Framework První verze (2008) součástí.net Frameworku Od verze 6 (2013) Opensource, mimo.net Framework CodeFirst i DatabaseFirst Líné vyhodnocování Podpora LINQ Podpora MSSQL, Oracle, MySQL,... Radek Janoštík (Univerzita Palackého v Olomouci) Základy programování 4 - C# 26.3.2017 5 / 14
EF instalace NuGet Package Manager Ruční linkování knihoven pracné (verze, závislosti, hledání knihoven v různých zdrojích) NuGet Package Manager správce balíčků s repozitáři (podobně jako v Linuxu) Pravý klik na projekt Manage NuGet Packages Správa verzí, licencí, závislostí Možno více zdrojů Možno vytvářet vlastní balíčky Balíčky per projekt nebo per solution Radek Janoštík (Univerzita Palackého v Olomouci) Základy programování 4 - C# 26.3.2017 6 / 14
EF vytvoření modelu = definice tříd, které chceme uchovávat v databázi Pozor na CodeFirst konvence https: //msdn.microsoft.com/en-us/library/jj679962(v=vs.113).aspx např. Property obsahující id bude primární klíč Odkaz na jinou entitu pomocí virtual + Id Např.: public class Student { public int Id {get; set; public string Name {get; set; public int AddressId {get; set; public virtual Address Address {get; set Radek Janoštík (Univerzita Palackého v Olomouci) Základy programování 4 - C# 26.3.2017 7 / 14
EF vytvoření kontextu Objekt reprezentující připojení k databázi using System.Data.Entity; Předek: DbContext Pro každou entitu DbSet Např.: public class UniversityContext : DbContext { public UniversityContext(string connstringname) : base(connstr { public DbSet<Address> Addresses { get; set; public DbSet<Student> Students { get; set; public DbSet<Subject> Subjects {get; set; Lze dodefinovat názvy sloupců... Radek Janoštík (Univerzita Palackého v Olomouci) Základy programování 4 - C# 26.3.2017 8 / 14
Připojení databáze Zjištění connection stringu Nastavení connection stringu v konfiguraci aplikace App.config: <configuration> <configsections> </configsections> <connectionstrings> <add name="universityconnection" providername="system.data.sqlclient" connectionstring="data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=Something.m </connectionstrings> <startup> <supportedruntime version="v4.0" sku=".netframework,version=v4.5.2" /> </startup> </configuration> Radek Janoštík (Univerzita Palackého v Olomouci) Základy programování 4 - C# 26.3.2017 9 / 14
Přístup k datům vložení záznamu Vytvoření záznamu try { using (UniversityContext ctx = new UniversityContext("UniversityConnection")) { Address a = new Address() { City = "Olomouc", Street = "17. Listopadu", Number = 14 ; Student s = new Student() { Address = a, Name = "Karel Vomáčka" ; ctx.students.add(s); ctx.savechanges(); catch (Exception e){ Console.WriteLine(e); Vždy potřeba uložit změny ctx.savechanges() Automatické vložení/uložení všech dotyčných entit Radek Janoštík (Univerzita Palackého v Olomouci) Základy programování 4 - C# 26.3.2017 10 / 14
Přístup k datům čtení dat LINQ dotaz na DbSet try { using (UniversityContext ctx = new UniversityContext("UniversityConnection")) { foreach (Student st in ctx.students.where(p =>p.address.city == "Olomouc" )) { Console.WriteLine($"{st.Name, {st.id"); catch (Exception e) { Console.WriteLine(e); Zobrazení vygenerovaných dotazů: ctx.database.log = Console.WriteLine; Radek Janoštík (Univerzita Palackého v Olomouci) Základy programování 4 - C# 26.3.2017 11 / 14
Přístup k datům změna dat Pouhá změna property u entity try { using (UniversityContext ctx = new UniversityContext("UniversityConnection")) { Student s = ctx.students.firstordefault(p => p.id == 1); if (s!= null) { s.name = "Bedřich Smetana"; s.subjects.add(ctx.subjects.firstordefault(p => p.name == "VYSL")); ctx.savechanges(); catch (Exception e) { Console.WriteLine(e); Radek Janoštík (Univerzita Palackého v Olomouci) Základy programování 4 - C# 26.3.2017 12 / 14
Přístup k datům smazání dat Nejdříve najdeme entitu Student s = ctx.students.firstordefault(p => p.id == 1); Poté ji odstraníme ctx.students.remove(s); ctx.savechanges(); Smaže jen tuto entitu, ty které obsahuje nemusí Jde nastavit smazání všech souvisejících, mohou být ale navázány jinam Radek Janoštík (Univerzita Palackého v Olomouci) Základy programování 4 - C# 26.3.2017 13 / 14
Úkol Navrhnout vhodnou strukturu databázových objektů pro uložení studentů (v rozsahu studentipredmetu.xml z minulých hodin) a jejich známek Vytvořit DB strukturu pomocí CodeFirst Vložit do databáze data studentů a náhodně jim (rozumně) vygenerovat známky Pomocí LINQ dotazů a EntityFrameworku provést všechny úkoly z minulého cvičení: Výběr unikátních jmen a příjmení (5. - 15.), vymazání, editace, výpis studentů se známkami. Radek Janoštík (Univerzita Palackého v Olomouci) Základy programování 4 - C# 26.3.2017 14 / 14