Download presentation
Presentation is loading. Please wait.
Published byἌδαμος Αυγερινός Modified over 6 years ago
1
Web programming and advanced development techniques
Database access layers DbConnection/DbReader (Not required!) DataSet (Not required!) LINQ / Entity Framework
2
Web programming and advanced development techniques
Database access layers DbConnection/DbReader (Not required!) DataSet (Not required!) LINQ / Entity Framework
3
SQL Server / SQL Express / LocalDB
MSSQL: typically used by small and medium-sized companies SQL Express: smaller edition: max 10GB/database, max 1 CPU, max 1GB RAM Earlier VS versions (x<2012): SQL Express was installed alongside the developer environment (Data Source=.\SQLEXPRESS) Available since VS 2010, default since VS 2012: LocalDB, an on-demand library that uses a database file (similar to sqlite (Data Source = (localdb)\v11.0) ) We will use this (in Windows authentication mode) The computers have MSSQL 2014 Express as well, if needed
4
DbConnection vs DataSet vs LINQ
Various abstraction layers DbConnection The most basic access layer, pure SQL, string SQL commands, object array result-set DataSet Above the SQL layer; a strongly-typed and GUI-centered layer; strongly typed methods for the various operations DB-LINQ / Entity Framework Above the SQL layer; a strongly-typed and data-centered, well organized MVC/ORM (Object Relational Mapping) layer: tables are nothing more than collections of entities; special queries Basic operations: Connect/initialization; insert; update; delete; query; connection with GUI elements
5
Web programming and advanced development techniques
Database access layers DbConnection/DbReader (Not required!) DataSet (Not required!) LINQ / Entity Framework
6
ADO.NET: DbConnection/DbReader
Old-fashioned data access (not MVC / ORM – connected mode) Advantage: fast, simple Cons: hard to modify and to change technology/storagene, must handle if the connection is lost, hard to manage the types Different implementations for different database servers Common base classes for the common operations Connection: DbConnection SQL/RPC execution: DbCommand Read SQL results: DbDataReader Specific descendant classes for the different database servers: SqlConnection (MSSQL System.Data.SqlClient), MySqlConnection (MySQL MySql.Data.MySqlClient), NpgsqlConnection (PostgreSQL - Npgsql), OracleConnection (Oracle System.Data.OracleClient)
7
1. Initialization string connStr Source=.\SQLEXPRESS;Initial Catalog=nikdb;User ID=nik;Password=kin"; SqlConnection conn; private void button15_Click(object sender, EventArgs e) { conn = new SqlConnection(connStr); conn.Open(); MessageBox.Show("CONNECTED"); }
8
1. Initialization (MySQL, Postgre)
case server_type.mysql: FConnStr = "server = " + FServer + ";\n" + "database = " + FDb + ";\n" + "user id = " + FUser + ";\n" + "password = " + FPass + ";\n"; FDatabase_Connection = new MySqlConnection(FConnStr); break; case server_type.postgre: FDatabase_Connection = new NpgsqlConnection(FConnStr);
9
1. Initialization (Oracle)
case server_type.oracle: FConnStr = "data source = " + FServer + ";\n" + "user id = " + FUser + ";\n" + "password = " + FPass + ";\n"; FDatabase_Connection = new OracleConnection(FConnStr); break;
10
2. INSERT private void button18_Click(object sender, EventArgs e) { SqlCommand comm = new SqlCommand("insert into EMP (ENAME, MGR, DEPTNO, EMPNO) values ('BILL', NULL, 20, 1000)", conn); SqlDataReader reader=comm.ExecuteReader(); MessageBox.Show(reader.RecordsAffected.ToString()); reader.Close(); }
11
3. UPDATE private void button18_Click(object sender, EventArgs e) { SqlCommand comm = new SqlCommand("update EMP set ENAME='JOE' where EMPNO=1000", conn); SqlDataReader reader=comm.ExecuteReader(); MessageBox.Show(reader.RecordsAffected.ToString()); reader.Close(); }
12
4. DELETE private void button18_Click(object sender, EventArgs e) { SqlCommand comm = new SqlCommand("delete from EMP where empno=1000", conn); SqlDataReader reader=comm.ExecuteReader(); MessageBox.Show(reader.RecordsAffected.ToString()); reader.Close(); }
13
5. SELECT private void button14_Click(object sender, EventArgs e) { listBox1.Items.Clear(); SqlCommand comm = new SqlCommand("select * from EMP where sal>=3000 order by ename", conn); SqlDataReader reader = comm.ExecuteReader(); while (reader.Read()) listBox1.Items.Add(reader["ENAME"].ToString()); } reader.Close(); Cél: azon nevekkel feltölteni egy listboxot, akiknek a fizetése >= 3000
14
Web programming and advanced development techniques
Database access layers DbConnection/DbReader (Not required!) DataSet (Not required!) LINQ / Entity Framework
15
ADO.NET: DataAdapter/DataSet/DataTable
Old-fashioned data access (not MVC), disconnected mode Advantages: no need for writing specific SQL commands, simpler connection to GUI controls Cons: hard to modify and change between technologies/storages Typically only works with MSSQL (or: via .NET connector or standardized ODBC drivers: might be unstable/buggy) Uses automatically generated, table-dependent, strongly typed classes (~200KB is normal for a two-table database) After the auto-generation, specific classes for tables/fields: TableAdapter: Table description, database-connection, operations DataSet: database representation, unification of tables BindingSource: Data source connection for the controls
16
Creating a DataSet We need the Server explorer (in Express Edition: Database Explorer) and the Data Sources (shift+alt+d) windows Server explorer: Add connection Type: Microsoft SQL Server Server Name: .\SQLEXPRESS, SQL Server Authentication, User: nik, Pass: kin, Save password, Database name: nikdb Data sources: Add new data source Database / DataSet Select connection, „Include sensitive data” „Save connection string to the application file”, select tables After this, we can simply drag & drop the table from the Data sources window into the form, and the application is ready
17
1. Initialization private void button5_Click(object sender, EventArgs e) { eMPTableAdapter.Fill(nikdbDataSetVariable.EMP); MessageBox.Show("CONNECTED"); }
18
2. INSERT private void button8_Click(object sender, EventArgs e) { DataRow ujsor = nikdbDataSetVariable.EMP.NewRow(); //NewEmpRow() is also useable ujsor["ENAME"] = "BILL"; ujsor["MGR"] = DBNull.Value; ujsor["DEPTNO"] = 20; ujsor["EMPNO"] = 1000; nikdbDataSetVariable.EMP.Rows.Add(ujsor); eMPTableAdapter.Update(nikdbDataSetVariable); MessageBox.Show("DONE"); }
19
3. UPDATE private void button7_Click(object sender, EventArgs e) { DataRow dr = nikdbDataSetVariable.EMP.Rows[0]; dr.BeginEdit(); dr["ENAME"] = "JOE"; dr.EndEdit(); nikdbDataSet valtozas=(nikdbDataSet)nikdbDataSetVariable. GetChanges(DataRowState.Modified); if (valtozas.HasErrors) { nikdbDataSetVariable.RejectChanges(); } else { nikdbDataSetVariable.AcceptChanges(); eMPTableAdapter.Update(valtozas); }
20
4. DELETE private void button6_Click(object sender, EventArgs e) { DataRow dr = nikdbDataSetVariable.EMP.Rows[0]; dr.Delete(); nikdbDataSetVariable.AcceptChanges(); eMPTableAdapter.Update(nikdbDataSetVariable); } DataRow dr = nikdbDataSetVariable.EMP.Select("empno=1000")[0]; // THIS IS NOT THE LINQ EXTENSION METHOD, ONLY IT HAPPENS TO HAVE THE SAME NAME! A kód papíron működik (VS2005-ben még ezt használtam ) … Most teszteltem VS2010 alatt: mintha működne (a 14 soros táblánál 14x működik, 15-ödszörre ahogy kell, kiakad, hogy „dataset is empty”)… Közben meg fizikailag a táblából nem töröl semmit valamiért: a program újraindítása után a táblában megint 14 sor van.
21
5. SELECT private void button12_Click(object sender, EventArgs e) { listBox1.Items.Clear(); foreach (DataRow dr in nikdbDataSetVariable.EMP.Select("sal>=3000")) listBox1.Items.Add(dr["ENAME"].ToString()); } Cél: azon nevekkel feltölteni egy listboxot, akiknek a fizetése >= 3000
22
Advanced Programming Database access layers
DbConnection/DbReader (Not required!) DataSet (Not required!) LINQ / Entity Framework
23
ORM = Object Relational Mapping – Task
HIDDEN physical data layer that works with SQL statements External operations: must be dialect-independent Dialect-independent conversion: execute the operations independent from the actual SQL dialect / storage approach Thus, the upper layer should not see an SQL language: Lambda expressions (Java Stream Api/C# LINQ) or a self-made query language (Doctrine) or simple CRUD methods (Active Record systems) Instance storage The upper layer only sees typed class instances The query results are converted to instances/collections Instances can be shared amongst operations Using the ORM, the upper layers see the database as an in-memory object storage, independent from the actually used physical storage model
24
ORM = Object Relational Mapping – examples
C#: Entity Framework Java: Hibernate/JPA Python: Django ORM, SQLAlchemy Ruby on Rails PHP: Eloquent, Propel, Doctrine
25
Doctrine DQL
26
Java + Hibernate + Stream API
27
C# + Entity Framework + LINQ
28
EF layers
29
Entity Framework (LINQ: to SQL / to Entities)
Older, similar syntax but COMPLETELY DIFFERENT APPROACH! Supports only direct mapping and only MSSQL dialect „Rapid development” ??? (or: “should not have been released”) Generate classes: Project/Add Class/LINQ to SQL classes ADO.NET Entity Framework (LINQ to Entites) Newer, full ORM, supports N:M relations Can work with other dialects (Oracle, MySQL, Postgres...) Generate clases: Data sources / Add new data source / Database / Entity Data Model Newer VS versions: Project / Add New Item / Data / ADO.NET Entity Data Model
30
Entity model creation alternatives
Code First: first write the classes, then map/generate the database (POCO classes!) Database/SQL First: auto-generate the classes from an already existing database Model First (OBSOLETE): We can „draw” the data model (= class diagram) ( )
31
Entity Framework versions
EF1 = EF3.5 .NET 3.5 (2008) EF4 .NET 4 (2010) „POCO support, lazy loading, testability improvements, customizable code generation and the Model First workflow” EF4.1 „first to be published on NuGet. This release included the simplified DbContext API and the Code First workflow” (2011) the strange ObjectContext api is replaced with the better DbContext api EF4.3 „Code First Migrations” (2012) usable ORM! EF5 (2012), API changes … EF6 (2013), API changes … EF (2014), EF 6.2 (2017) widely used and a reliable, good ORM!
32
Entity Framework Core EF7: RC … „EF7 introduces some significant changes and improvements over EF6.x. Because EF7 is based on a new core, the features from EF6.x do not automatically carry over into EF7. EF6.x may still be the most suitable release for many applications” EF7 renamed, then released as: EF Core „Because of the fundamental changes in EF Core we do not recommend attempting to move an EF6.x application to EF Core unless you have a compelling reason to make the change. You should view the move from EF6.x to EF Core as a port rather than an upgrade.„
33
Entity Framework Core EF Core 1.0: (with ASP.NET Core 1.0) EF Core 2.0: (with ASP.NET Core 2.0) EF Core 2.1: (with ASP.NET Core 2.1) LAZY LOAD + GROUP BY, elértünk az EF 6.1 szintjére… EF Core 2.2: end of 2018, „small release” - Good: Client-side/query keys, Cmdline, Mixed client/server evaluation, Raw SQL with LINQ, Statement batches, DbContext pooling - No problem: no graphical visualization, no EDMX, Entityless many-to-many - Small problem: Limited inheritance models, No entity splitting, No stored procedures, No Database.Log - HUGE problem: No change tracking via Proxies, No lifecycle hooks, No update model from database
34
Creating LocalDB In-Solution
Project / Add New Item / Service-based Database (this will be an SQL server file. Local Database: SQL server compact file) We can use both, service-based is preferred: EmpDept.mdf First we load the data, then we generate the classes In-Profile Server Explorer -> Right click (Data Connections) -> Add Connection ( Microsoft SQL Server + .Net provider for SQL Server <OK>) Server name = (localdb)\v11.0 , Database name = EMPDEPT <OK> "Database does not exists. Attempt to create?" <YES> We could follow the „Create New SQL Server Database” button, with similar steps
35
Load the data Right click on the new DB, new query, copypaste everything from the creator SQL, Execute, then the query window can be closed (right click on new DB/tables, refresh: tables should be shown) Project, Add new Item, ADO.NET Entity Data Model <ADD>; Generate from database <NEXT>; select the MDF file + save connection settings <NEXT>; EF6.0 <NEXT>; check both tables + Model namespace = EmpDeptModel <FINISH> Depending on security settings: Template can harm your computer, click ok to run ... <OK> <OK> ( ) Result: automatically generated classes (just like with the DataSet), but these are simpler (POCO) or generic classes ~30KB for the two-table database The tables are always re-set to the initial state!
36
1. Initialization ED = new EmpDeptEntities(); Console.WriteLine("Connect OK"); // DbSet<T> type, LINQ extension methods // LINQ query syntax is possible too // IEnumerable<T> vs IQueryable<T> // Lazy loading string deptName = ED.EMP.First().DEPT.DNAME; var oneWorker = from worker in ED.EMP where worker.ENAME.Contains("E") select worker; Console.WriteLine(worker.Count());
37
2. INSERT var worker = new EMP() { ENAME = "BILL", MGR = null, DEPTNO = 20, EMPNO = 1000 }; ED.EMP.Add(worker); // Saved via change tracking ED.SaveChanges(); Console.WriteLine("Insert OK");
38
3. UPDATE var worker = ED.EMP.Single(x => x.EMPNO == 1000); worker.ENAME = "JOE"; ED.SaveChanges(); Console.WriteLine("Update OK");
39
4. DELETE var worker = ED.EMP.Single(x => x.EMPNO == 1000); ED.EMP.Remove(worker); ED.SaveChanges(); Console.WriteLine("Delete OK");
40
5. SELECT string s = "", sep=""; foreach (var w in ED.EMP.Where(worker => worker.SAL >= 3000)) { s += sep + w.ENAME; sep = ","; } Console.WriteLine(s); Console.WriteLine( string.Join(";", ED.EMP.Select(x => x.ENAME)) ); Cél: azon nevekkel feltölteni egy listboxot, akiknek a fizetése >= 3000
41
+1 JOIN var workers = from w in NE.EMP join d in NE.DEPT on w.DEPTNO equals d.DEPTNO select new { w.ENAME, w.SAL, d.DNAME }; OR with Lazy Loading: select new { w.ENAME, w.SAL, w.DEPT.DNAME Mindegy h hogyan állítom be az adatforrást
42
Advantages of an ORM We have ZERO dialect-dependent SQL code
We can switch dialect/server without modifying anything Instead of string-based SQL commands, we use a query syntax that is checked by the compiler Any error in a query will be detected at compile-time Instead of string concatenation (and string/object parameters) we use actual variables as query parameters Avoid SQL injection The query results are not generic anonymous type / object / associative array Instead: strongly typed value / instance / list of known types By placing an extra layer on top of an ORM layer, we can achieve total storage separation and easy testing Repository Pattern, Dependency Injection Pattern
43
Disadvantages of using an ORM
“ORM is a terrible anti-pattern that violates all principles of object-oriented programming, tearing objects apart and turning them into dumb and passive data bags. There is no excuse for ORM existence in any application” It is one opinion, but typical drawbacks: Harder to configure Bigger memory footprint Bigger CPU requirement Weak/hard support of more complex queries Hard to optimize
44
ORM speed (C#)
45
ORM speed (PHP)
46
Tables
47
Exercises Add a „Service-Based Database” with the name EmpDept.mdf, fill this using the orademo.sql and then create the Entity classes! Determine the average income for every department names (income = salary + commission)! Determine the biggest department! Increase the salary for the people in the job with the smallest sum salary. The job with the smallest sum should have the same sum as the job with the second to smallest sum; distribute the extra salary evenly amongst the workers! Delete the workers who were hired in the 30 days after the hire date of the president!
48
Sources http://msdn.microsoft.com/en-us/library/bb882674
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.