1 LinQ Introduction. Outline Goals of LinQ Anatomy of a LinQ query More expression examples LinQ to Objects LinQ to XML LinQ to SQL 2.

Slides:



Advertisements
Similar presentations
The Microsoft Technical Roadshow 2007 Language Enhancements and LINQ Daniel Moth Developer & Platform Group Microsoft Ltd
Advertisements

What is a Database By: Cristian Dubon.
LINQ and Collections An introduction to LINQ and Collections.
Extension Methods, Anonymous Types LINQ Query Keywords, Lambda Expressions Svetlin Nakov Telerik Corporation
C# and LINQ Yuan Yu Microsoft Research Silicon Valley.
LinqToSharePoint SandBoxed Solution Shakir Majeed Khan
Damien Guard (BSc, MBCS) Guernsey Software Developer Forum Language Integrated Query:
LINQ: Language-Integrated Queries (To be included in C # 3.0) Technology developed by Anders Hejlsberg & friends at Microsoft (2005) Presented by Tal Cohen.
Introduction to Structured Query Language (SQL)
C# 3.0 Tom Roeder CS fa. Version 3 From PDC 2005 preview compiler available LINQ: language-integrated query High level points: adds native query.
The Microsoft Technical Roadshow 2007 Advances for Data in VS “Orcas” Mike Taulty Developer & Platform Group Microsoft Ltd
Introduction to Structured Query Language (SQL)
2.3 Cool features in C# academy.zariba.com 1. Lecture Content 1.Extension Methods 2.Anonymous Types 3.Delegates 4.Action and Func 5.Events 6.Lambda Expressions.
C# 3.0 and LINQ Pavel Yosifovich CTO, Hi-Tech College
A tour of new features introducing LINQ. Agenda of LINQ Presentation We have features for every step of the way LINQ Fundamentals Anonymous Functions/Lambda.
XML files (with LINQ). Introduction to LINQ ( Language Integrated Query ) C#’s new LINQ capabilities allow you to write query expressions that retrieve.
LINQ Programming in C# LINQ CSE Prof. Roger Crawfis.
8 Copyright © 2004, Oracle. All rights reserved. Creating LOVs and Editors.
 Introduction  What is LINQ  Syntax  How to Query  Example Program.
Extension Methods Programming in C# Extension Methods CSE Prof. Roger Crawfis.
LINQ, An IntroLINQ, An Intro Florin−Tudor Cristea, Microsoft Student Partner.
MongoDB An introduction. What is MongoDB? The name Mongo is derived from Humongous To say that MongoDB can handle a humongous amount of data Document.
CHARLES UNIVERSITY IN PRAGUE faculty of mathematics and physics Advanced.NET Programming I 11 th Lecture Pavel Ježek
Getting familiar with LINQ to Objects Florin−Tudor Cristea, Microsoft Student Partner.
Putting it all together: LINQ as an Example. The Problem: SQL in Code Programs often connect to database servers. Database servers only “speak” SQL. Programs.
LINQ TO XML Mike Taulty Developer & Platform Group Microsoft UK
Advanced C#, part IV Niels Hallenberg IT University of Copenhagen (With thanks to Peter Sestoft and Kasper Østerbye) BAAAP – Spring 2009.
Extension Methods, Anonymous Types LINQ Query Keywords, Lambda Expressions Based on material from Telerik Corporation.
Monads Steve Goguen. About Me Web Developer for Allied Building Supply  ASP.NET, SQL Server, LINQ, etc. Website:
Introduction to LINQ Lecture # 19 August Introduction How do you interrogate/manipulate data? What if you could do the work in a type-safe," string-free.
Ronnie Saurenmann Principal Architect Microsoft Switzerland.
The.NET Language Integrated Query Project Anders Hejlsberg TLN306 Technical Fellow Microsoft Corporation.
Neal Stublen How does XMLReader work?  XmlReader.Read() Advances to next node XmlReader properties access node name, value, attributes,
 Language Integrated Query  Make query a part of the language  Component of.NET Framework 3.5  Shipped with Visual Studio 2008.
Hoang Anh Viet Hà Nội University of Technology Chapter 1. Introduction to C# Programming.
 Although VERY commonly used, arrays have limited capabilities  A List is similar to an array but provides additional functionality, such as dynamic.
Introduction to LINQ Chapter 11. Introduction Large amounts of data are often stored in a database—an organized collection of data. A database management.
C# 3.0 and LINQ Pavel Yosifovich CTO, Hi-Tech College
Language Integrated Query (LINQ). Data Access Programming Challenges Developers must learn data store-specific query syntax Multiple, disparate data stores.
C#: Future Directions in Language Innovation Anders Hejlsberg TLN307 Technical Fellow Microsoft Corporation.
Applied Linq Putting Linq to work Introducing… Class-A Kennisprovider Microsoft development Training Coaching Alex Thissen Trainer/coach.
Object Oriented Programming Generic Collections and LINQ Dr. Mike Spann
CSCI 3327 Visual Basic Chapter 8: Introduction to LINQ and Collections UTPA – Fall 2011.
Inside LINQ to Objects How LINQ to Objects work Inside LINQ1.
PROGRAMMING IN C#. Collection Classes (C# Programming Guide) The.NET Framework provides specialized classes for data storage and retrieval. These classes.
Satisfy Your Technical Curiosity C# 3.0 Raj Pai Group Program Manager Microsoft Corporation
CIS 200 Test 01 Review. Built-In Types Properties  Exposed “Variables” or accessible values of an object  Can have access controlled via scope modifiers.
IAP C# 2011 Lecture 2: Delegates, Lambdas, LINQ Geza Kovacs.
LINQ Language Integrated Query LINQ1. LINQ: Why and what? Problem Many data sources: Relational databases, XML, in-memory data structures, objects, etc.
Dr. Abdullah Almutairi Spring PHP is a server scripting language, and a powerful tool for making dynamic and interactive Web pages. PHP is a widely-used,
C# Fundamentals An Introduction. Before we begin How to get started writing C# – Quick tour of the dev. Environment – The current C# version is 5.0 –
BTM 382 Database Management Chapter 8 Advanced SQL Chitu Okoli Associate Professor in Business Technology Management John Molson School of Business, Concordia.
Chapter 11.  Large amounts of data are often stored in a database—an organized collection of data.  A database management system (DBMS) provides mechanisms.
Functional Programming Data Aggregation and Nested Queries Ivan Yonkov Technical Trainer Software University
Part 1: Overview of LINQ Intro to LINQ Presenter: PhuongNQK.
Jim Fawcett CSE681 – Software Modeling and Analysis Fall 2016
Jim Fawcett CSE681 – Software Modeling and Analysis Fall 2013
Intro to LINQ Part 2 – Concepts and LINQ to Objects
Language Integrated Query: (LINQ) An introduction
MIS Professor Sandvig MIS 324 Professor Sandvig
Introduction to LINQ Chapter 11 10/28/2015 Lect 4 CT1411.
Language Integrated Query (LINQ)
Introduction to LINQ Chapter 11.
Language Integrated Query (LINQ)
Advances for Data in VS “Orcas”
Advances for Data in VS “Orcas”
MIS Professor Sandvig MIS 324 Professor Sandvig
LINQ - 2 Ravi Kumar C++/C# Team.
Entity Framework & LINQ (Language Integrated Query)
CS4540 Special Topics in Web Development LINQ to Objects
Presentation transcript:

1 LinQ Introduction

Outline Goals of LinQ Anatomy of a LinQ query More expression examples LinQ to Objects LinQ to XML LinQ to SQL 2

Goals of LinQ Integrate data queries into.Net languages Before C# 3.0 you could use delegates, extension methods, anonyous methods and Visitor Pattern to make something similar to LinQ. But the syntax is messy and key points, eg. selection criteria, are not easy to read. 3

Goals of LinQ Provide a standardized way to query data Challenges: Different data types Different data representations (xml, sql, objects) Data organization Hierarchical – xml (and object) Relational – sql Before LinQ you should use different api’s for accessing databases, objects and xml LinQ provides one single way (nearly) to access it all LinQ works on collections that implements IEnumerable (the.Net language must therefore support generics) 4

Anatomy of a LinQ query An example: 5 string[] characters = { "Donald", "Mickey", "Goofy", "Minnie", "Daisy", "Scrooge" }; IEnumerable query = from c in characters where c.StartsWith("M")!=true orderby c descending select c; foreach(string s in query) Console.WriteLine(s); string[] characters = { "Donald", "Mickey", "Goofy", "Minnie", "Daisy", "Scrooge" }; IEnumerable query = from c in characters where c.StartsWith("M")!=true orderby c descending select c; foreach(string s in query) Console.WriteLine(s); The collection is here a simple string array But the same query will run for more complex objects, SQL, XML etc.

Demo With objects After demo, note the following: Intellisense Static type checking 6

Query Expressions Types of expressions Filtering e.g. Where Projections e.g. Select Joining e.g. Join Partitioning e.g Skip and Take Ordering e.g OrderBy Aggregation e.g. Count and Sum 7

Providers The same expresions works on different kinds of data This is done by accessing a provider A LinQ provider is a gateway to a querable type. There are several builtin providers Objects SQL XML Active Directory PLINQ (Parallel processing) Etc. And many custom providers too: LinQ to Amazon LinQ to Twitter Etc. 8

How are people in Aalborg ? Twitter demo Get LinqToTwitter here: 9 var twitterCtx = new TwitterContext();.. var queryResults = from search in twitterCtx.Search where search.Type == SearchType.Search && search.Attitude == Attitude.Positive && search.GeoCode == " , ,25km" select search; foreach (SearchEntry entry in srch.Results) Console.WriteLine(entry.Text); var twitterCtx = new TwitterContext();.. var queryResults = from search in twitterCtx.Search where search.Type == SearchType.Search && search.Attitude == Attitude.Positive && search.GeoCode == " , ,25km" select search; foreach (SearchEntry entry in srch.Results) Console.WriteLine(entry.Text);

Deferred Execution Normally the query is not executed before the result is needed This is when only lazy operators (where, orderby...) are used. When busy operators are used, the query is executed immediately (count, average) 10 var adults = from p in personList where p.Age > 18 orderby p.Age select (p.FirstName + " " + p.LastName); Console.WriteLine(adults.Count()); personList.Add(new Person { FirstName = “Ib", LastName = “Madsen", Age = 35 }); foreach (var p in adults) { Console.WriteLine(p.ToString()); } var adults = from p in personList where p.Age > 18 orderby p.Age select (p.FirstName + " " + p.LastName); Console.WriteLine(adults.Count()); personList.Add(new Person { FirstName = “Ib", LastName = “Madsen", Age = 35 }); foreach (var p in adults) { Console.WriteLine(p.ToString()); }

Composed Queries A composed query is a query that uses another query. In behind LinQ will make new query that is optimized for the given data store (objects, sql, xml...) 11 var adults = from p in personList where p.Age > 18 orderby p.Age select (p.FirstName + " " + p.LastName);..... var query = from p in adults where p.StartsWith("B") select p; foreach (var p in query) Console.WriteLine(p); var adults = from p in personList where p.Age > 18 orderby p.Age select (p.FirstName + " " + p.LastName);..... var query = from p in adults where p.StartsWith("B") select p; foreach (var p in query) Console.WriteLine(p);

Encapsulate Query It is not possible directly to return an anonymous type And it wouldn’t be nice either Therefore it not is possible to return a query if is declared as var The nice way here is to declare the query as an IEnumerable and return that. If the query is a join or a projection etc. then make a class that maps the output from ‘select’ and return a collection of objects of that class 12

Collections of objects We already seen how to access a collection of objects this is called LinQ to objects LinQ to objects is a good alternative to foreach and other iterations 13

Custom providers And we have seen use of a custom provider to access a webservice. 14 If it is a plain webservice that returns a collection, then we could have accessed that with LinQ to objects

In the next part, we will see how to access XML and SQLServer. 15

LinQ to XML Uses the System.Xml.Linq namespace Is somewhat different from other xml api’s The XElement class is the key class. When instanizing a XElement you can generate the whole document in the constructor 16 XElement doc = new XElement("Inventory", new XElement("Car", new XAttribute("ID","1000"), new XElement("Color", "Red"), new XElement("Make", "Ford")) ); XElement doc = new XElement("Inventory", new XElement("Car", new XAttribute("ID","1000"), new XElement("Color", "Red"), new XElement("Make", "Ford")) ); Red Ford

Use LinQ to generate XML 17 XElement personDoc = new XElement("People", from c in personList orderby c.LastName select new XElement("Person", new XAttribute("Age", c.Age), new XElement("FirstName", c.FirstName), new XElement("LastName", c.LastName) )); XElement personDoc = new XElement("People", from c in personList orderby c.LastName select new XElement("Person", new XAttribute("Age", c.Age), new XElement("FirstName", c.FirstName), new XElement("LastName", c.LastName) )); Caroline Bendtsen Bjarne Hansen...

Use LinQ to search in XML 18 XElement doc = MakeXElementFromList(); var query = from p in doc.Elements("Person") where Convert.ToInt32(p.Attribute("Age").Value) < 40 select p; foreach (var p in query) Console.WriteLine(p.Value); XElement doc = MakeXElementFromList(); var query = from p in doc.Elements("Person") where Convert.ToInt32(p.Attribute("Age").Value) < 40 select p; foreach (var p in query) Console.WriteLine(p.Value);

LinQ to SQL LinQ accesses the sql db through a datacontext class The class can be created with a wizard in VisualStudio, where you select which tables to access Only SQLServer is supported from Microsoft But dbms vendors like Oracle are also providing support for LinQ. (haven’t tested it myself). An (better?) alternative is to use the Entity Framework 19

Use the wizard to create the DataContext class Add a new item to the project using the ”LINQ to SQL classes” template. Select the database and the tables that shall be available 20

Select the tables Note that wizard knows the carnalities 21

Using LinQ to SQL Select orders from a certain customer 22 NorhwindDataContext dc = new NorhwindDataContext(); var orders = from o in dc.Orders where o.CustomerID == "ALFKI" orderby o.OrderDate select o.OrderID; foreach (var o in orders) Console.WriteLine(o); NorhwindDataContext dc = new NorhwindDataContext(); var orders = from o in dc.Orders where o.CustomerID == "ALFKI" orderby o.OrderDate select o.OrderID; foreach (var o in orders) Console.WriteLine(o); SELECT [t0].[OrderID] FROM [dbo].[Orders] AS [t0] WHERE [t0].[CustomerID] ORDER BY [t0].[OrderDate] SELECT [t0].[OrderID] FROM [dbo].[Orders] AS [t0] WHERE [t0].[CustomerID] ORDER BY [t0].[OrderDate]

A join Write products that the customer has brought 23 var orders = from o in dc.Order_Details join p in dc.Products on o.ProductID equals p.ProductID where o.Order.CustomerID == "ALFKI" orderby o.Order.OrderDate select new { product = p.ProductName, orderDate = o.Order.OrderDate }; foreach (var p in orders) Console.WriteLine("{0:dd-MM-yyyy}: {1}", (DateTime)p.orderDate, p.product); var orders = from o in dc.Order_Details join p in dc.Products on o.ProductID equals p.ProductID where o.Order.CustomerID == "ALFKI" orderby o.Order.OrderDate select new { product = p.ProductName, orderDate = o.Order.OrderDate }; foreach (var p in orders) Console.WriteLine("{0:dd-MM-yyyy}: {1}", (DateTime)p.orderDate, p.product); {SELECT [t1].[ProductName] AS [product], [t2].[OrderDate] AS [orderDate] FROM [dbo].[Order Details] AS [t0] INNER JOIN [dbo].[Products] AS [t1] ON [t0].[ProductID] = [t1].[ProductID] INNER JOIN [dbo].[Orders] AS [t2] ON [t2].[OrderID] = [t0].[OrderID] WHERE [t2].[CustomerID] ORDER BY [t2].[OrderDate] } {SELECT [t1].[ProductName] AS [product], [t2].[OrderDate] AS [orderDate] FROM [dbo].[Order Details] AS [t0] INNER JOIN [dbo].[Products] AS [t1] ON [t0].[ProductID] = [t1].[ProductID] INNER JOIN [dbo].[Orders] AS [t2] ON [t2].[OrderID] = [t0].[OrderID] WHERE [t2].[CustomerID] ORDER BY [t2].[OrderDate] }

Join Join is similar to Inner Join in SQL That means that it is the intersection between two sequences The inner sequence is a keyed collection, that makes it a lot faster than a subquery (or traversing in a nested loop) Note that it uses Equals instead of == (remember the difference?) 24

Group Group transforms a sequence into a sequence of groups that contains a subsequence 25 var products = from p in dc.Products group p by p.Category.CategoryName; foreach (var group in products) { Console.WriteLine("\nCategory: {0}", group.Key); foreach (var product in group) Console.WriteLine(product.ProductName); var products = from p in dc.Products group p by p.Category.CategoryName; foreach (var group in products) { Console.WriteLine("\nCategory: {0}", group.Key); foreach (var product in group) Console.WriteLine(product.ProductName);

Use objects as keys It is possible to use objects as keys. It can be of an anonymous type or of a defined class 26 var products = from p in dc.Products group p by new { cname = p.Category.CategoryName, cid = p.Category.CategoryID } into productCategories orderby productCategories.Key.cid select productCategories; foreach (var group in products) { Console.WriteLine("\nID: {0} Category: {1}", group.Key.cid,group.Key.cname); foreach(var product in group) Console.WriteLine(product.ProductName); } var products = from p in dc.Products group p by new { cname = p.Category.CategoryName, cid = p.Category.CategoryID } into productCategories orderby productCategories.Key.cid select productCategories; foreach (var group in products) { Console.WriteLine("\nID: {0} Category: {1}", group.Key.cid,group.Key.cname); foreach(var product in group) Console.WriteLine(product.ProductName); }

Group into 27 Group will end the query. Use ‘Into’ to continue the query var products = from p in dc.Products group p by p.Category.CategoryName into productCategories orderby productCategories.Key select productCategories; foreach (var group in products) { Console.WriteLine("\nCategory: {0}", group.Key); foreach (var product in group) Console.WriteLine(product.ProductName); var products = from p in dc.Products group p by p.Category.CategoryName into productCategories orderby productCategories.Key select productCategories; foreach (var group in products) { Console.WriteLine("\nCategory: {0}", group.Key); foreach (var product in group) Console.WriteLine(product.ProductName);

Grouping and projecting Make a projection on the content of the group 28 var products = from p in dc.Products group p by p.Category into productCategories where productCategories.Count() < 8 orderby productCategories.Key.CategoryName select new { cname = productCategories.Key.CategoryName, count = productCategories.Count() }; foreach (var group in products) { Console.WriteLine("Category: {0}, Count: {1}", group.cname,group.count); } var products = from p in dc.Products group p by p.Category into productCategories where productCategories.Count() < 8 orderby productCategories.Key.CategoryName select new { cname = productCategories.Key.CategoryName, count = productCategories.Count() }; foreach (var group in products) { Console.WriteLine("Category: {0}, Count: {1}", group.cname,group.count); }

Nested queries Nested queries are similar to nested SELECT in SQL. But be careful: O(n 2 ) 29 var products = from p in dc.Products where p.CategoryID == (from c in dc.Categories where c.CategoryName == "Seafood" select c).First().CategoryID select p; foreach (var p in products) { Console.WriteLine("Category: {0}, Product: {1}", p.Category.CategoryName, p.ProductName); } var products = from p in dc.Products where p.CategoryID == (from c in dc.Categories where c.CategoryName == "Seafood" select c).First().CategoryID select p; foreach (var p in products) { Console.WriteLine("Category: {0}, Product: {1}", p.Category.CategoryName, p.ProductName); }

Let keyword Reuse expressions 30 var products = from p in dc.Products group p by p.Category into productCategories let upperName= productCategories.Key.CategoryName.ToUpper() where productCategories.Count() < 8 orderby upperName select new { cname = upperName, count = productCategories.Count() }; foreach (var group in products) { Console.WriteLine("Category: {0}, Count: {1}", group.cname,group.count); } var products = from p in dc.Products group p by p.Category into productCategories let upperName= productCategories.Key.CategoryName.ToUpper() where productCategories.Count() < 8 orderby upperName select new { cname = upperName, count = productCategories.Count() }; foreach (var group in products) { Console.WriteLine("Category: {0}, Count: {1}", group.cname,group.count); }

A few words on operators The LinQ operators are implemented with extension methods (recall the.Where method) You can define your own operator by defining an extension method And you can overwrite the existing operators But be careful: The operator should still do the same sort of things as it was originally intended for. E.g. the Where operator should still be a filter operator If the operator is not an aggregator it should be lazy to support deferred execution. Use ”yield” keyword when returning items from lazy operators 31

Define a contrary version of Where The extension method must be in another namespace 32 using System; using System.Collections.Generic; using LinQExamples; namespace MaryTheContrary //Rasmus Modsat { public static class ExtensionMethods { public static IEnumerable Where( this IEnumerable sequence, Func predicate) { foreach (Person p in sequence) { if (!predicate(p)) //Contrary yield return p; } }} using System; using System.Collections.Generic; using LinQExamples; namespace MaryTheContrary //Rasmus Modsat { public static class ExtensionMethods { public static IEnumerable Where( this IEnumerable sequence, Func predicate) { foreach (Person p in sequence) { if (!predicate(p)) //Contrary yield return p; } }}

Use of the contrary ‘where’ The compiler differs between different where’s by the namespace. So you must use ‘using 33 using MaryTheContrary;.... IEnumerable nonAdults = from p in personList where p.Age > 18 orderby p.Age select p; foreach(Person p in nonAdults) Console.WriteLine(“First Name: {0} Age:{1}", p.FirstName,p.Age); using MaryTheContrary;.... IEnumerable nonAdults = from p in personList where p.Age > 18 orderby p.Age select p; foreach(Person p in nonAdults) Console.WriteLine(“First Name: {0} Age:{1}", p.FirstName,p.Age);

LINQPad Utility for interactively search with LinQ You can get it here: 34

Exercise 1 You can get the processes that runs on the machine with IEnumerable System.Diagnostics.Process.GetProcesses() The Process object has several properties, e.g. ProcessName returns the name of the process WorkingSet64 returns the allocated memory in bytes TotalProccessorTime return the CPU time that has been used TODO: Write and test a LinQ query that returns the processes that has allocated more than 50mb (1mb=10124*1024 bytes) and ordered by process name. The allocated memory should be outputted in mb. Do the same in a foreach without LinQ. 35

Exercise 2, advanced Continued from exercise 1. You will get an exception if you try to get TotalProcessorTime on a process that you do not own, e.g. a system process And it not possible to filter those processes out  ! A workaround could be like this: 36 IEnumerable processes = Process.GetProcesses(); foreach (Process p in processes){ try { Console.WriteLine("Process Name: {0} Time: {1}", p.ProcessName, p.TotalProcessorTime); } catch (Exception e){ Console.WriteLine("Process Name: {0} Time: {1}", p.ProcessName, null); }} IEnumerable processes = Process.GetProcesses(); foreach (Process p in processes){ try { Console.WriteLine("Process Name: {0} Time: {1}", p.ProcessName, p.TotalProcessorTime); } catch (Exception e){ Console.WriteLine("Process Name: {0} Time: {1}", p.ProcessName, null); }} TODO: Override “select” so it inserts null’s for values that are not available. Test it in a LinQ expression (To get it work: Remove “Using System.Linq”, and also implement “Where”)