Download presentation
Presentation is loading. Please wait.
Published byDerrick Neal Modified over 9 years ago
1
Further exploring database operations from C#/.NET Jim Warren, jim@cs.auckland.ac.nz COMPSCI 280 S2 2015 Enterprise Software Development
2
Today’s learning objectives To be able to use the LINQ (language-integrate query) approach for database queries in C#/.NET To be able to update the database from C#/.NET To conceptualise an application in terms of CRUD (create, read, update, delete) operations To consider the state of an object instance in relation to the database context COMPSCI 2802
3
Last lecture… We learned to connect to a database, set up a model of its tables and create queries like: This is OK, but it has some disadvantages We don’t get support from the IDE for the query itself It’s an arbitrary string – no type checking, no intellisense It’s a bit of a pain to always need to figure out the type of the returned instances It’s also a potential security hole… COMPSCI 2803 var x2 = db.Database.SqlQuery ("select * from employee");
4
SQL injection COMPSCI 2804
5
The LINQ approach Makes the query actually a statement in the C# language SQL’s select-from-where is turned on its head a bit Makes the intellisense work better to use from-where-select order In this case the return value is a collection of objects of a class we’ve already defined in our Model Because we had said: public DbSet Employees { get; set; } and had defined the Employee class with property names exactly aligned to the columns of the DBMS table COMPSCI 2805 using (EmployeesContext db = new EmployeesContext()) { var emps = from e in db.Employees where e.DateOfBirth.Year < 1975 select e; string surname1=emps.First().surname } We get access to all C#’s operators, too!
6
LINQ Join We could, of course, have sent join queries to MySQL as a string, but LINQ brings Join into C# Notice the ‘select’ Even if we included in the model definitions of the ‘categories’ and ‘products’ tables, we’d need a new class to hold the combination of a product name and a category name The ‘new’ statement is constructing an anonymous type with properties ProductName and Category innerJoinQuery will be implicitly typed to a generic collection of instances with the generic’s type parameter being this new 2-property anonymous type We can still do a foreach statement on innerJoinQuery to loop through the results COMPSCI 2806 var innerJoinQuery = from category in db.categories join prod in db.products on category.ID equals prod.CategoryID select new { ProductName = prod.Name, Category = category.Name }; Notice we said ‘equals’ as a keyword (not the = sign); this gives system most flexibility to exploit indices or other optimise the join
7
More LINQ – group by Get a count of how many employees with each surname Use ‘group’… ‘by’ keyword pair Note use of ‘into’ and naming a second index variable (‘g’ in this case) Note the special property Key is the thing we grouped by COMPSCI 2807 var cnts = from emp in db.Employees group emp by emp.Surname into g select new {s=g.Key, cnt=g.Count()}; foreach (var c in cnts) Console.WriteLine("Key: " + c.s + " Count: " + c.cnt);
8
Or method based GroupBy Use GroupBy method allowing a lambda to specify just what we want the grouping Key to be And you can apply one method onto the result of another COMPSCI 2808 foreach (var c in db.Employees.GroupBy(a=>a.Surname.Substring(0,1))) Console.WriteLine("Key2: " + c.Key+ " Count2: " + c.Count()); foreach (var c in db.Employees.GroupBy(a => Math.Floor(a.DateOfBirth.Year/10f))) Console.WriteLine("Key2: " + c.Key + "0's Count2: " + c.Count()); foreach (var c in db.Employees.Where(a=>a.Surname.CompareTo("F")>=0).GroupBy(a=>a.Su rname.Substring(0,1))) Console.WriteLine("Key2: " + c.Key+ " Count2: " + c.Count()); Count of employees by first letter of surname Count of employees by decade of birth
9
What about the rest of the CRUD?! CRUD: Create, Read, Update, Delete A CRUD matrix can be a useful specification for the scope of programming tasks E.g. to describe the ‘life cycle’ of each entity in a system; e.g. a hotel reservation On some screen (e.g. ‘booking’) it is created (SQL INSERT, not CREATE like making a new table) There may be a screen to UPDATE it (e.g. ‘change booking’) which probably also reads the current value (‘R’ of CRUD, SQL SELECT) And there will be one or more ways to DELETE it (e.g. from a cancellation action on the change booking screen or a dedicated cancellation screen, and also once the person has checked in) – then again, you might not actually delete in a SQL sense, but UPDATE it to cancelled or utilised status COMPSCI 2809
10
CRUD matrix (well, for one entity) Program (or ‘screen’)Entity=reservation Make reservationC Check reservationR Review/change reservationRU Review/cancel reservationRD* Client arrives (takes up reserved room)D** COMPSCI 28010 For a more involved system you may have many entities represented as further columns Each cell marked with a subset of the letters in ‘CRUD’ * Or update status to cancelled ** Or update status to taken
11
The UPDATE Native SQL version Given that I have a reference to an object emp of class Employee with updated values: COMPSCI 28011 using (EmployeesContext db = new EmployeesContext()) { string sql=String.Format( "UPDATE employee SET Surname='{0}',GivenNames='{1}',"+ "DateOfBirth='{2:yyyy-MM-dd}' WHERE id={3}", emp.Surname,emp.GivenNames,emp.DateOfBirth,emp.id); db.Database.ExecuteSqlCommand(sql);... } Here we’re just building the text of a SQL command with the help of String.Format to plug in the parameters from our C# code at the curly braces (note the 3 rd parameter - #2 counting from 0! – is formatted so MySQL recognises the date literal; also note carefully the double quotes interpreted by C# and the signle quotes that are for MySQL Then we just.ExecuteSqlCommand (as compared to doing. SqlQuery) on the database context to tell MySQL to have at it Re-establish the database connection
12
Native INSERT Similar to the UPDATE, once we have a database context established we can do INSERT (or DELETE) SQL COMPSCI 28012 string sql_ins = String.Format("INSERT INTO employee (GivenNames,SurName,DateOfBirth) "+ "VALUES ('{0}','{1}','{2:yyyy-MM-dd}')","Bob", "Barker",DateTime.Now); db.Database.ExecuteSqlCommand(sql_ins); string sql_del = "delete from employee where GivenNames='Bob'"; db.Database.ExecuteSqlCommand(sql_del);
13
The UPDATE v2 Entity Framework version If you’ve gotten an object from the database, the system tracks that that object is “attached” to the database context If you want to update a record Retrieve it Change properties of the object as you wish Save the changes COMPSCI 28013 using (EmployeesContext db = new EmployeesContext()){ var updEmp = from emp in db.Employees where emp.Surname == "Barker" select emp; foreach (Employee e3 in updEmp) e3.Surname = "Good"; db.SaveChanges();... } Every employee with surname ‘Barker’ gets updated to surname ‘Good’
14
INSERT by adding If you simply create a ‘new’ object of the class of a record, it isn’t attached to the database context by default However, you use the appropriate DbSet’s Add method to attach it Use the database context’s SaveChanges method to make the insertion stick COMPSCI 28014 using (EmployeesContext db = new EmployeesContext()) {... var e1 = new Employee{GivenNames="Tommy", Surname="Tank"}; db.Employees.Add(e1); db.SaveChanges(); Adds a new employee with name “Tommy Tank”, letting the ‘id’ be supplied automatically and leaving DateOfBirth unspecified (probably will be set to 1 Jan 1 AD !) Note curly-brace “object initializer” syntax. Invokes constructor and then assigns the specified values to the named properties of the new object
15
Delete To delete Get a handle on the relevant object(s) (e.g. with a query, like we did for update) Invoke the Remove method of the DbSet with the object to delete as a parameter Note: if deleting (or in some cases updating) where there are foreign key constraints you may need to think carefully about the ‘cascade’ of effects with respect to referential integrity (see https://technet.microsoft.com/en- us/library/aa902684(v=sql.80).aspx) COMPSCI 28015 using (EmployeesContext db = new EmployeesContext()) {... var deletedEmp = from emp in db.Employees where emp.Surname == "Tank" select emp; foreach (Employee emp in deletedEmp) db.Employees.Remove(emp); db.SaveChanges();
16
Where we’re up to We’ve learned some basics of.NET and C# We’ve seen that we can interact with our DBMS by sending it native SQL or using C#/.NET language-embedded syntax (LINQ and Entity Framework) Now… Work the second labsheet (if you haven’t already) Get seriously into Assignment 2 See you other side of the break! FYI, I’m on leave first week of the break, but will be at work and answering questions second week of the break COMPSCI 28016
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.