advanced web development using c# david figge [email protected] session 3 last update: 1/12page...
TRANSCRIPT
Copyright (C) 2012 by David Figge. All Rights Reserved.
Advanced Web Development using C#
David [email protected]
Session 3
Last Update: 1/12 Page 1
Copyright (C) 2012 by David Figge. All Rights Reserved.
Advanced Web Development using C#
Check-In
Last Update: 1/12 Page 2
Copyright (C) 2012 by David Figge. All Rights Reserved.
Session 1: Introductions, Overview Gridviews Controls
Session 2: More on GridView Controls
Session 3: GridView Once Again ListViews
Session 4: The DetailsView and
FormView Caching
Session 5: File Streams Using XML
Session 6: User Controls
Session 7: CSS and Themes
Session 8: LINQ
Linq with DataSets Linq with Entities
Session 9: Deployment
Session 10: Final Lab
Class 2 Schedule
Last Update: 1/12 Page 3
Copyright (C) 2012 by David Figge. All Rights Reserved.
Advanced Web Development using C#
User Controls
Last Update: 1/12 Page 4
Copyright (C) 2012 by David Figge. All Rights Reserved.
User Controls
The core set of controls that ASP gives you is a great set of tools
However, sometimes it just doesn't meet the needs you have
Enter: User Controls
Last Update: 1/12 Page 5
Copyright (C) 2012 by David Figge. All Rights Reserved.
User Controls
A user control is a collection of existing controls put together into a grouping that can be used repeatedly throughout the Web site This code can include standard HTML or ASP
controls This code is reusable throughout the Web
site Written properly, it can be ported to other
Web apps as well You can add your own properties as well, so
you can define the interface to the control
Last Update: 1/12 Page 6
Copyright (C) 2012 by David Figge. All Rights Reserved.
User Controls
The easiest way to see how User Controls work is to simply create and use one
We're going to create a simple user control in a new Web page on our app It won't be linked in to the main system You can remove it later if you wish
Ready?
Last Update: 1/12 Page 7
Copyright (C) 2012 by David Figge. All Rights Reserved.
Creating a User Control
Last Update: 1/12
Add a new item to your project Web User Control
Name it "Spinner.ascx" This control is going to provide a
"spinner" capability that rotates through numbers as you press the up and down arrow buttons
Before we get started, let's take a look at the source code for the User Control
Page 8
Copyright (C) 2012 by David Figge. All Rights Reserved.
Code
Example Creating a User Control
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind=... %><asp:TextBox ID="textColor" runat="server" /><asp:Button Font-Bold="True" ID="buttonUp" runat="server"
Text="^" OnClick="buttonUp_Click" /><asp:Button Font-Bold="True" ID="buttonDown" runat="server"
Text="v" OnClick="buttonDown_Click" />
Last Update: 1/12 Page 9
Add this code to the ASCX page.
Alternatively, you can drag the controls onto the design window and set the properties…
Copyright (C) 2012 by David Figge. All Rights Reserved.
Code
Example Creating a User Control
public partial class spinner : System.Web.UI.UserControl
{
protected int currentIndex;
public int maxValue;
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
currentIndex = Int16.Parse(ViewState["currentIndex"].ToString());
}
else
{
currentIndex = 1;
if (maxValue == 0) maxValue = 10;
DisplayNumber();
}
}
// Continued...
Last Update: 1/12 Page 10
This goes into the Code Behind page for the user control.
Copyright (C) 2012 by David Figge. All Rights Reserved.
Code
Example Creating a User Control
protected void DisplayNumber() { textColor.Text = currentIndex.ToString(); ViewState["currentIndex"] = currentIndex.ToString(); } protected void buttonUp_Click(object sender, EventArgs e) { if (currentIndex == 1) currentIndex = maxValue; else currentIndex--; DisplayNumber(); } protected void buttonDown_Click(object sender, EventArgs e) { if (currentIndex == maxValue) currentIndex = 1; else currentIndex++; DisplayNumber(); }}
Last Update: 1/12 Page 11
Copyright (C) 2012 by David Figge. All Rights Reserved.
Creating a User Control
Now it's time to insert the control into a page
Create a new Web page For consistency, include Site.Master
Add this code to the page…
Last Update: 1/12 Page 12
Copyright (C) 2012 by David Figge. All Rights Reserved.
Code
Example Adding a User Control
<%@ Page Title="" Language="C#" ... %><%@ Register TagPrefix="uc" TagName="Spinner" Src="~/spinner.ascx" %>...<asp:Content ID="Content1" ContentPlaceHolderID="MainContent"...> <uc:Spinner id="Spinner1" runat="server" maxValue="8" /></asp:Content>
Last Update: 1/12 Page 13
This goes into the source window of the new page that has the user control on it. It
should display and work.
Copyright (C) 2012 by David Figge. All Rights Reserved.
User Control Notes
User controls are great for small groups of controls/code that need to be used in multiple places on a site
You can use either HTML or ASP code in user controls
User controls (as you saw) can have properties and events
Last Update: 1/12 Page 14
Copyright (C) 2012 by David Figge. All Rights Reserved.
User Control Exercise
Last Update: 1/12
Your nexttask is to adda title bar toeach page ofyour application. This will, of course, be a User Control In it, you will be able to set the title The title bar will be displayed above each
of the pages' content to explain what it is in a consistent way
Here are the steps…Page 15
Copyright (C) 2012 by David Figge. All Rights Reserved.
User Control Exercise
Last Update: 1/12
You user control will consist of A table, with a single cell in it
The table should extend all across the content area (100%) Set the background color of the cell to #4b6c9e. This will
match the heading colors In the cell, have a label control
The text should be white, pretty large, and centered in the cell
Create a property, Title, that can be set as you place the control in the web page
Set the title in Page_Load. If there is no title set (or it's empty – "") set the control's visibility to false.
Put the control in each of the web pages you already have and set it with the appropriate title
Page 16
40 Minutes
Copyright (C) 2012 by David Figge. All Rights Reserved.
Advanced Web Development using C#
Cascading Style Sheets and Themes
Last Update: 1/12 Page 17
Copyright (C) 2012 by David Figge. All Rights Reserved.
The problem
HTML elements are designed to be flexible. For example <h1>
My Web Page</h1>
This prints "My Web Page" in the default font, size, and color for Heading 1
<h1> <font face="courier" size="+3" color=red> <strong> My Web Page </strong> </font></h1>
This prints "My Web Page" in courier, large size, red, and bold This is the way formatting was applied until HTML 4
The problem was obvious There was no way to easily define a shared set of formatting
definitions to a web page HTML Styles allowed us to gain some control over this
Let's see how these work…
Last Update: 1/12 Page 18
Copyright (C) 2012 by David Figge. All Rights Reserved.
Code
Example HTML Styles
<html xmlns="http://www.w3.org/1999/xhtml" ><head> <title>David's Page</title>
</head>
<body> <h1>This is My Web Page</h1> <p>Welcome to my page!</p> <p>I hope you enjoy your time here.</p></body></html>
Last Update: 1/12 Page 19
This is My Web PageWelcome to my page!I hope you enjoy your time here.
We'll start with a basic page. A title is printed, along with a welcome
message.
Although it's a simple page, we can already see that formatting each
element via <Font> tags would be awkward and difficult to maintain.
Copyright (C) 2012 by David Figge. All Rights Reserved.
Code
Example HTML Styles
<html xmlns="http://www.w3.org/1999/xhtml" ><head> <title>David's Page</title> <style type="text/css"> body{ color: purple; background-color: yellow; } </style>
</head>
<body> <h1 class="myTitle">This is My Web Page</h1> <p class="myBody">Welcome to my page!</p> <p>I hope you enjoy your time here.</p></body></html>
Last Update: 1/12 Page 20
This is My Web PageWelcome to my page!I hope you enjoy your time here.
Here we're adding a style. This style affects everything in the body of the
HTML file.
Styles are defined in the <head> section of the document
We define the style using the <style> tag. The type of language used is
text/css.
The body style says that the (text) color is purple and the background is yellow.
Only items defined in the style are applied (so text size, for example, isn't
set by the style).
So the result is a consistently applied style that affects the whole body.
Copyright (C) 2012 by David Figge. All Rights Reserved.
Code
Example HTML Styles
<html xmlns="http://www.w3.org/1999/xhtml" ><head> <title>David's Page</title> <style type="text/css"> .myTitle { color: purple; background-color: yellow; } .myBody { color: Blue; font: Arial; font-size: large; } </style></head>
<body> <h1 class="myTitle">This is My Web Page</h1> <p class="myBody">Welcome to my page!</p> <p class="myBody">I hope you enjoy your time here.</p></body></html>
Last Update: 1/12 Page 21
This is My Web PageWelcome to my page!I hope you enjoy your time here.
You can also define custom styles. These must be applied individually to
an element.
Here we define 2 styles, .myTitle and .myBody
Styles are applied using the class tag within the element.
The body tag could also have been included here, which would apply to any element that didn't have a 'class'
attribute applied to it.
So now we're at a point where there's one specific place where all styles are set, and changes apply to the whole
page. We're getting closer…
But the problem with this approach is that each style is specific to the web
page. We need to be able to have styles that apply to entire sites. Enter
Cascading Style Sheets…
Copyright (C) 2012 by David Figge. All Rights Reserved.
Cascading Style Sheets
So, just what are Cascading Style Sheets? Cascading Style Sheets (CSS) is a language
used to describe the look and formatting of a document
You just saw examples of using the language Although most often associated with web sites, CSS
is designed work with any kind of XML/HTML presentation document
The purpose of CSS is to separate the content of the document (e.g. the web pages) from the document presentation (layout, colors, fonts)
By doing so you can 1. Provide a consistent look to the entire document2. Have a central place to make changes to
formatting and have it apply site-wideLast Update: 1/12 Page 22
Copyright (C) 2012 by David Figge. All Rights Reserved.
Cascading Style Sheets
CSS was introduced in HTML 4 (1997), and is supported by every significant browser today
The 'Cascading' part of CSS is what allows us to address the problem we just saw
Where styles need to be shared between pages Cascading Style Sheets can be defined at the
web site level and can be applied to all pages To apply a style sheet (external file) to a page
In the <head> section, specify so using the <link> tag
<link href="StyleSheet.css" rel="stylesheet" type="text/css">
Last Update: 1/12 Page 23
Copyright (C) 2012 by David Figge. All Rights Reserved.
Setting Styles
So you just saw an example of a style body {
padding-left: 11em; font-family: "Times New Roman"; color: purple; background-color: #d8da3d }
So let's take a look at some of the options connected with this language Looking at the example above, we'll look at the
options for "body" (called selectors) – what are the choices
here? What are the style setting options? What are the acceptable values for those options?
Last Update: 1/12 Page 24
Copyright (C) 2012 by David Figge. All Rights Reserved.
Setting Styles – (Major) Selector Options
Selector Example Description
.class .subhead Applies to all elements with class="subhead"
Element p Applies to all specified (<p>) elements
Element, element div,p Applies to <div> and <p> elements
Element element div p Applies to all <p> elements in <div> elements
:link a:link Applies to all unvisited links (<a> tags)
:visited a:visited Applies to all visited links (<a> tags)
:hover a:hover Applies to links when moused-over
#id #name Applies to elements with id="name"
Last Update: 1/12 Page 25
Copyright (C) 2012 by David Figge. All Rights Reserved.
Setting Styles – (Major) Style Options
Last Update: 1/12 Page 26
Type Property Description
Font font Sets the font properties in one declaration
font-family Specifies the font family. Can specify an ordered comma-separated list in case some can't be found
font-size Specifies the size of the font
font-style Specifies the font style (e.g. italic)
font-variant Used for small-caps font
Font-weight Specifies the font weight (e.g. bold)
List list-style Sets the list properties in one declaration
list-style-image Sets the image for the list-item marker
Margin margin Sets the margin properties in one declaration
margin-xxx Sets the -left, -right, -top, -bottom margin
Padding padding Sets the padding properties in one declaration
padding-xxx Sets the -left, -right, -top, -bottom padding
Copyright (C) 2012 by David Figge. All Rights Reserved.
Setting Styles – (Major) Style Options
Last Update: 1/12 Page 27
Type Property Description
Text color Sets the color of the text
letter-spacing Increases or decreases the space between characters
line-height Sets the line height
text-align Sets the horizontal text alignment
text-indent Sets the indentation of the first line in a text-block
text-transform Sets the capitalization of text
vertical-align Sets the vertical alignment of the element
word-spacing Increases or decreases the spacing between words
text-wrap Specifies line breaking rules for text
Background background-color Sets the background color of an element
Border border Sets the border properties of an element
Check out www.w3schools.com/cssref for more options
Copyright (C) 2012 by David Figge. All Rights Reserved.
Some windows that can help
Visual Studio has several interface elements to help you with styles
Let's look at The CSS Properties window The Apply Styles window The Manage Styles window
Also remember You can set the class of the element via
the properties window
Last Update: 1/12 Page 28
Copyright (C) 2012 by David Figge. All Rights Reserved.
Playing a bit
Last Update: 1/12
Let's play around a bit with CSS Examine the CSS file associated with our
site Change some of the settings to see what
happens We may have to add some regular text…
Page 29
Copyright (C) 2012 by David Figge. All Rights Reserved.
Well, That Was Different
As you can see, CSS can only go so far in an ASP-based site
This is because much of the site is built with ASP-based components Which don't fall under the html-based
CSS style rules So, to provide the same (needed)
functionality, ASP has themes…
Last Update: 1/12 Page 30
Copyright (C) 2012 by David Figge. All Rights Reserved.
What are Themes?
Themes allow you to define a set of style attributes that you want applied to controls
Themes are designed to be site-wide Themes have these characteristics
They are control-base, not HTML-based So they allow you to define the look of a control
Themes are applied on the server The theme is applied as the page is created on the
server. CSS is client-based. Themes don't cascade like CSS
When there's a conflict between the theme and an individual control setting, the theme wins (default)
Last Update: 1/12 Page 31
Copyright (C) 2012 by David Figge. All Rights Reserved.
What's a Skin?
Themes are application specific The theme is within the folder ~\App_Themes
You can have multiple themes, each in a separate folder within App_Themes
A .skin file (in the theme folder) is used to apply the theme
The .skin file is a text file with a list of control tags with (only) those settings which should be applied to controls of that type
Example:<asp:TextBox runat="server" ForeColor="Green" BackColor="Gray" />
Specifying a skinID The above example applies to all TextBoxes. To apply
to specific elements, specify the skinID attribute in the .skin file and the control
Last Update: 1/12 Page 32
Copyright (C) 2012 by David Figge. All Rights Reserved.
How do I set a theme
Associating the Skin For the theme to be applied, you specify the
"theme" attribute in the @Page declaration In your control, you specify the skinID (if there is
one) Using images relative to theme…
Note that images used in themes should specify location from the app root (~/)
Relative locations don't work as well as the theme file is not where the .cs files are
Using config files to set theme To make your theme apply globally to your
application, you can use your .config file <pages theme="MyTheme" />
Last Update: 1/12 Page 33
Copyright (C) 2012 by David Figge. All Rights Reserved.
Let's Play Again
Last Update: 1/12
It's usually easier to see how this works in action
Let's create a theme for our app Add a new item: Skin File
(restaurant.skin) Let's change the default look of a
GridView First we'll use the default (no skinID) Then apply a skinID
Page 34
Copyright (C) 2012 by David Figge. All Rights Reserved.
Master Pages
Since we're discussing this stuff anyway, let's include Master Pages
What are Master Pages Master Pages allow you to apply a cross-app
"template" to your pages Master Pages are very useful in provide both a
common look-and-feel, as well as (typically) a consistent navigation structure
Applying a Master Page Typically you'll add a page using the "Web
Page Using Master Page" option, but they are specified in the MasterPageFile attribute in the @page line
Last Update: 1/12 Page 35
Copyright (C) 2012 by David Figge. All Rights Reserved.
Master Pages
Note that Master Pages are set up differently than typical pages The <Head> section is in the master page
This allows it to consistently apply the same head information on each page
It also contains the <body> There are 2 Content place holders
These are sections where your code goes One is used in the Master Page (e.g. for the navigation
scheme) The other is used for your page contents (MainContent)
Master Pages can provide a common look and feel that is not easily attained in other ways
Last Update: 1/12 Page 36
Copyright (C) 2012 by David Figge. All Rights Reserved.
Styles Exercise
Last Update: 1/12
Create a new style for our Web site Use whatever CSS and Themes settings you need
Modify the settings so All text in list/view/grid controls are
Arial (if not available, then Helvetica, San-Serif)Extra-small size (so more data fits on the page)
Text in the menu, title bars, and any other header type places
Impact (if not available, then Arial, San-Serif)Large size
Text in menu descriptions should be Tahoma (if not available, Arial, San-Serif)
Medium Size Use the rest of the time to investigate CSS and
Themes (it's a doing-it-to-learn-it thing…)
Page 37
35 Minutes…
Copyright (C) 2012 by David Figge. All Rights Reserved.
Advanced Web Development using C#
Language INtegrated Query
Last Update: 1/12 Page 38
Copyright (C) 2009 by David Figge. All Rights Reserved.
Language Integrated Query Review
Linq is C#'s query construct, similar to SQL
However, because it's integrated into the language, it has these advantages over SQL SQL is string-based. Linq, as a part of C#,
can be checked for errors at compile time Because Linq is collection-based (rather than
cursor based), you can sort and filter the entire collections more efficiently
Let's look at an example of LINQ to refresh our memories…
Last Update: 3/09 Page 39
Copyright (C) 2009 by David Figge. All Rights Reserved.
Code
Example Linq Example
static void Main(string[] args){ string[] Instruments = { "Saxophone", "Piano", "Flute",
"Guitar", "Cello", "Drums", "Trumpet" };
IEnumerable<String> names = from i in Instruments where i.Length > 5 select i;
foreach (string s in names) Console.WriteLine(s);}
Last Update: 3/09 Page 40
So we start off with a collection of strings (in this case, Instruments)
The next line is, obviously, the Linq line. Linq uses several keywords…
Similar to foreach(string i in Instruments), we have from i in Instruments.
The “from” variable (i) is the one that will take on the value of each item in
Instruments (one at a time) so we can examine the contents.
Instruments is, of course, the collection that we are querying.
The select clause is the one that actually adds an element to the
results.
Those 3 elements are required in all Linq statements: the from, in, and
select clauses.
Most Linq statement also include a where clause. This reduces the result set to only those matching the clause (in this case, i.Length > 5). Note that we use the i variable here, because
during the execution of the statement, it holds the current
element being examined.
Questions so far?
A linq statement returns an IEnumerable object, in this case based
on strings (since we were using strings). Among other things,
IEnumerable works well with foreach.
So here we use the foreach statement to display the result collection from the Linq query.Does this make sense to everyone?
This is similar to the SQL statement (if a database had strings like Instruments)
select Name from Instruments where Name.Length > 5
Copyright (C) 2009 by David Figge. All Rights Reserved.
Code
Example Linq Example: Even Digits
static void Main(string[] args){ int[] digits = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
IEnumerable<int> evens = from num in digits where num % 2 == 0 select num;
foreach (int i in evens) Console.Write("{0} ",i.ToString());
Console.WriteLine();}
Last Update: 3/09 Page 41
Just to make sure we've got it, let's look at another example. This one retrieves and displays even digits.
We start with a collection of integers called digits.
Because we’re collecting integers, we’ll store the results in an IEnumerable<int>
data type (called evens)
Here's our Linq statements. We're looking at each digit. If it's an even
number (num % 2 == 0) we select it, which puts it into the result set.
This displays the numbers (separated by a space), then moves to the next
line after all have been printed.
Is this clearto everyone?
Copyright (C) 2009 by David Figge. All Rights Reserved.
Implicitly Typed Variables
C# supports a variable data type using the keyword var, for example:
So, in this case, result takes on the data type based on what GetData returns
There are some great uses for this, but one really convenient one is Linq!
Here's the Even Number code using var:Last Update: 3/09 Page 42
var result = GetData(); // var set based on return type
Copyright (C) 2009 by David Figge. All Rights Reserved.
Code
Example Even Digits with var
static void Main(string[] args){ int[] digits = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
var evens = // Was Ienumerable<int> evens = from num in digits where num % 2 == 0 select num;
foreach (int i in evens) Console.Write("{0} ",i.ToString());
Console.WriteLine();}
Last Update: 3/09 Page 43
As you can see, this makes the line much more readable. And since the compiler knows the data type, why
not have it be automatic?
Although var has a convenience element, there are also times when you simply have
to use var (because the data type is not defined). We’ll see that in a few minutes…
Copyright (C) 2009 by David Figge. All Rights Reserved.
Using Linq with Classes
Of course, you can use Linq with strings and integers, most often you'll use it with classes You can either put the results into an
IEnumerable<ClassType> type, or a var Let’s put together a query that takes
movies (from a movies collection) and pulls out all those directed by Steven Spielberg…
Last Update: 3/09 Page 44
Copyright (C) 2009 by David Figge. All Rights Reserved.
Code
Example Movies Example
var spielbergs = from movie in Movies where movie.DirectedBy == "Steven Spielberg" select movie;
foreach(Movie m in spielbergs) Console.WriteLine(m.Title);
Last Update: 3/09 Page 45
Here we look at each movie in the Movies collection
Now we display the title of each movie. The entire movie object was
placed in the results collection (spielbergs), so all the Movie properties are available to us.
If the DirectedBy property of the object is "Steven Spielberg" we select the record.
Anyone have questions on any of this that we’ve covered?
Copyright (C) 2009 by David Figge. All Rights Reserved.
Anonymous Result Types
There can be disadvantages to retrieving entire classes of data using Linq When data is remote and classes are large,
you might pass lots of unnecessary data over a network connection
Anonymous Types can help An anonymous type is just that: a type
(class) that is created temporarily and without a name
In this case, it can be used by Linq to store the results of a query
Let’s look at an example…
Last Update: 3/09 Page 46
Copyright (C) 2009 by David Figge. All Rights Reserved.
Code
Example An Anonymous Class Example
... var dispdata = from ba in BankAccounts select new { ba.Name, ba.Balance };
foreach(var i in dispdata) Console.WriteLine("{0} has a balance of {1}", i.Name, i.Balance);
Last Update: 3/09 Page 47
So we start off looking pretty normal. Select all records from the BankAccounts collection.
However, instead of grabbing the entire record (perhaps hundreds of fields), we grab only two.
This is the Anonymous Type syntax. It says, “create a new type” containing just these elements.
Note that we have to use the variable type identifier var, since the return type doesn’t
really even have a name.
Here’s our foreach loop. Again, we have to use the var keywords for the type, since it doesn’t really have a name.
When accessing i, we can use the Name and Balance properties (defaulted from the BankAccount type).
Cust=ba.Name, Bal=ba.Balance };
Note that you can also name the elements as you select them using this syntax. That would also imply changes to
the display line (to reference Cust and Bal)…
Like this.
i.Cust, i.Bal);
Does this make sense. Any questions on this?
Copyright (C) 2009 by David Figge. All Rights Reserved.
Deferred Execution
It’s important to note that Linq uses Deferred Execution This means that the query isn’t actually
executed until you request the results For example, within the foreach loop
This has a couple of benefits If the underlying data changes, your
loop uses it You don't search through data that you
don't need Let's look at this in action…
Last Update: 3/09 Page 48
Copyright (C) 2009 by David Figge. All Rights Reserved.
Code
Example Deferred Execution
static void Main(string[] args){ int[] numbers = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
var evens=from i in numbers where i % 2 == 0 select i;
foreach (int i in evens) // Produces 0 2 4 6 8 Console.Write("{0} ", i.ToString()); Console.WriteLine();
numbers[5] = 10;
foreach (int i in evens) // Produces 0 2 4 10 6 8 Console.Write("{0} ", i.ToString()); Console.WriteLine();}
Last Update: 3/09 Page 49
This code should loop pretty familiar. We go through numbers and print the even ones, based
on the linq statement above.
But here we change things up a bit. We change the element that had 5 in it to be 10 (an even number).
Now, without executing the Linq statement again, we do another
foreach loop. This time it shows the element with 10.
What this shows us is that the linq statement is saved, then executed each time (in this case) the foreach loop requests it. That’s what’s meant by
deferred execution.
This ‘connection’ is broken when the evens variable goes out of scope.
So one way you can force this ‘disconnect’ is to this is to copy the result set into (for example) an
array. If you aren’t using evens, it won’t be executing its associated linq statement.
Deferred Executionmake sense?
Copyright (C) 2009 by David Figge. All Rights Reserved.
Advanced Linq Operators
As you may be able to see, Linq is patterned after the SQL language Many of the keywords match SQL Phrasing is similar to SQL The difference is that Linq was designed to
work with internal data structures as well as external data (like databases)
So let’s take a look at some of the more advanced keywords of Linq Remember, although these were patterned
after and designed to work with SQL, you do not need a database to make these work!
Last Update: 3/09 Page 50
Copyright (C) 2009 by David Figge. All Rights Reserved.
Linq Query Operators
Last Update: 3/09 Page 51
Query Operators Meaning
from, in Used to define the base Linq expression to extract a subset of data from a container
where Used to specify a restriction to retrieved data
select Used to select a specific element from the container
join, on, equals, into Performs joins based on a specific key element
orderby, ascending, descending
Allows the resulting subset to be ordered ascending or descending
group, by Yields a subset that is grouped by a specified value
Let's see an examplewith orderby…
Copyright (C) 2009 by David Figge. All Rights Reserved.
Code
Example Orderby Example
var spielbergs = from movie in Movies where movie.DirectedBy == "Steven Spielberg" orderby movie.Title select movie;
foreach(Movie m in spielbergs) Console.WriteLine(m.Title);
Last Update: 3/09 Page 52
Make sense?
Copyright (C) 2012 by David Figge. All Rights Reserved.
Linq To Dataset
When working with databases, one of the more useful abilities of Linq is its ability to work with DataSets
After all, a DataSet is a collection of DataTable objects, which (in turn) is a collection of DataRow objects
However, working with DataSets introduce a couple of issues
First, DataSets don't expose strongly typed data And Linq requires this
Second, Linq requires results to be placed in a collection of type Ienumerable
Neither DataTable or DataRow implement this interface
Last Update: 1/12 Page 53
Copyright (C) 2012 by David Figge. All Rights Reserved.
Linq to DataSet
The solution to this first problem lies in an extension method Field<T>
This method allows you to take the weak typed results from DataTables/DataRows and convert them:string value = dataRow.Field<string>("Name");
This has the added benefit of translating database entries that are NULL to the C# value null (DataSet doesn't do this natively)
The solution to the second problem is to convert the DataTable/DataRow to support IEnumerable using the AsEnumerable extension method
IEnumerable rows=dataTable.AsEnumerable() So with these additions, we have code like…
Last Update: 1/12 Page 54
Copyright (C) 2012 by David Figge. All Rights Reserved.
Code
Example Linq to DataSet
DataSet movieDS= db.GetMoviesDataSet();
var spielbergs = from movie in movieDS.Tables["Movies"].AsEnumerable() where movie.Field<string>("DirectedBy") == "Steven Spielberg" select movie;
gridMovies.DataSource = spielbergs.AsDataView();gridMovies.DataBind();
Last Update: 1/12 Page 55
We start by creating a DataSet that represents the Movies database (in a dataset movieDS)
We're going to retrieve a collection of DataRow objects. To do that, we need to convert the
DataTables to an IEnumerable-based collection. Using .AsEnumerabble
And we do that here.To look at a specific database field, we use
the .Field<T> method (like this) to tell Linq that we're looking at a string object.
We have one more issue. In our Linq process, we lost the schema portion of the database tables.
Binding spielbergs directly would lose the ability to access non-public elements of the DataRow.
Fortunately, we can solve this by using one more extension method.
The .AsDataView() method restores the schema needed for data binding to work.
Copyright (C) 2012 by David Figge. All Rights Reserved.
Code
Example Linq to DataSet
DataSet movieDS= db.GetMoviesDataSet();
var spielbergs = from movie in movieDS.Tables["Movies"].AsEnumerable() where movie.Field<string>("DirectedBy") == "Steven Spielberg" select new {movie.Title, movie.Year};
gridMovies.DataSource = spielbergs;gridMovies.DataBind();
Last Update: 1/12 Page 56
An alternative to using .AsDataView() is to use anonymous classes to store the results. This
transfers the schema information that DataBind needs. Questions
on this?
Copyright (C) 2012 by David Figge. All Rights Reserved.
Let's Try It
Last Update: 1/12
Let's see if we can't get this to work… Add a new page to our program called
LinqTest In the Page_Load, add this code…
Page 57
Copyright (C) 2012 by David Figge. All Rights Reserved.
Code
Example LinqTest
protected void Page_Load(object sender, EventArgs e){ string cs = WebConfigurationManager .ConnectionStrings["ReservationsConnectionString"].ConnectionString; SqlConnection connection = new SqlConnection(cs); SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM Customers", connection); DataSet ds = new DataSet(); da.Fill(ds);
var matches = from customer in ds.Tables["Table"].AsEnumerable() orderby customer.Field<string>("Zip") select customer;
GridView1.DataSource = matches.AsDataView(); GridView1.DataBind();}
Last Update: 1/12 Page 58Type it in, then we’ll look at it…
First we set up the DataSet object. To do this we…
Load the connection string from the Web.Config file…Use it to create a new
SqlConnection object… Use the connection object with a SELECT statement to create
the Data Adapter…Use the Data Adapter to fill
a new DataSet object.
With me so far?
Now we do our query…
Our SELECT query from above put the results into the DataSet using a default table "Table". We use that,
invoking the AsEnumerable() method so Linq can use it.
We're pulling in customer data ordered by zipcode. Remember we have to use .Field<string>("Zip") so
Linq sees it as a string.
Finally, we set the DataSource property of
the GridView to the result set. We need
AsDataView() to generate the schema data needed
by the GridView.
Setting the DataSource property of the GridView
isn't enough. We also need to call DataBind to
populate the new data to the GridView. We do that
here.
Is everyone following?Let's do one last modification: to use Anonymous Classes…
Copyright (C) 2012 by David Figge. All Rights Reserved.
Code
Example LinqTest
protected void Page_Load(object sender, EventArgs e){ string cs = WebConfigurationManager .ConnectionStrings["ReservationsConnectionString"].ConnectionString; SqlConnection connection = new SqlConnection(cs); SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM Customers", connection); DataSet ds = new DataSet(); da.Fill(ds);
var matches = from customer in ds.Tables["Table"].AsEnumerable() orderby customer.Field<string>("Zip") select new { First = customer.Field<string>("FirstName"), Last = customer.Field<string>("LastName"), Zip=customer.Field<string>("Zip") };
GridView1.DataSource = matches; GridView1.DataBind();}
Last Update: 1/12 Page 59Make the mods, then we'll talk…
To use anonymous classes, instead of the "select customer" we have "select new { }",
with the braces containing the fields to
keep.
When using DataSets, we still have to use
the .Field<T> method to establish the data type.
Finally, with anonymous classes, we don't need
the AsDataView() call on the result set when
setting the DataSource.Have Ilost anyone?
Copyright (C) 2012 by David Figge. All Rights Reserved.
Linq to Entities
I wanted to touch on just a couple more elements having to do with Linq
The first is Linq to Entities I'm not going to cover this extensively,
as we covered it in a prerequisite course pretty thoroughly
Linq to Entities is a powerful tool that maps database tables into classes Allowing you to interact with database
data as objects in a collection…Last Update: 1/12 Page 60
Copyright (C) 2012 by David Figge. All Rights Reserved.
Linq To Entities
You start by creating a mapping You indicate what database tables you're interested in working
with Linq to Entities uses the database schema to create classes that
represent the data in the table These classes contain
Strongly typed data Properties (which only update if data changes) The classes are declared Partial so you can add functionality It even supports importing of stored procedures
You then load the database rows into objects and interact with them
Being an object oriented language, there's more you can do with objects that with database tables
You have full control over updates, deletions, inserts, etc. Most of these are mapped back to the database seamlessly
Linq to Entities is a significant tool in a developer's toolbelt! There's more in the book if you missed the previous classes on
Linq and Linq to Entities…Last Update: 1/12 Page 61
Copyright (C) 2012 by David Figge. All Rights Reserved.
Linq to XML
Like Linq to Entities brings Linq to Database tables, Linq to XML brings Linq capabilities to XML documents
In many cases, Linq can replace XSL processing, and with more control
It is, of course, a C#-specific solution To do this, you write a new XML document object that
has been changed (tranformed) from the original Given this document, you can then save it or use it within the
program… The "source" for the linq query can be any collection
object XML data, in-memory objects, DataSets
You then use anonymous type syntax to store the result set
Storing them into a new XElement object (whose constructor can create subelements as well)
Let's look at an example…
Last Update: 1/12 Page 62
Copyright (C) 2012 by David Figge. All Rights Reserved.
Code
Example Linq to XML
string xmlFile = Server.MapPath("menu.xml");XDocument doc = XDocument.Load(xmlFile);
XDocument newDoc = new XDocument( new XDeclaration("1.0", "utf-8", "yes"), new XElement("Menu", from meal in doc.Descendants("menuItem") orderby (string)meal.Element("title") select new XElement[] { new XElement("menuItem", new XElement("title",(string)meal.Element("title")), new XElement("summary",(string)meal.Element("summary")), new XElement("description",(string)meal.Element("description")), new XElement("price",(string)meal.Element("price")), new XElement("image",(string)meal.Element("image")) ) } ) ); newDoc.Save(Server.MapPath("") + "/newMenu.xml");
Last Update: 1/12 Page 63
This part simply loads the Menu.xml file (that we already have) into an XDocument object.
We're putting our transformation results into a new XDocument
object.We write out the version number and the root tag
(Menu).
Here's where Linq comes in. We're extracting each
menuItem, ordering it alphabetically, then
copying the element into the newDoc object.
At the end (mostly to see the results), we write it to
a file newMenu.xml.
Let's answer some questions on the code, then we'll look at the
output file…
Note the use of anonymous classes here.
We create a new class that is an array of new
XElement objects (stored into newDoc).
Copyright (C) 2012 by David Figge. All Rights Reserved.
Code
Example NewMenu.xml
<?xml version="1.0" encoding="utf-8" standalone="yes"?><Menu> <menuItem> <title>Boeuf Bourguignon</title> <summary>Beef Burgundy</summary> <description>Beef braised in red Burgundy, flavored with garlic, potatos, onions, and
mushrooms.</description> <price>$22</price> <image>Boeuf-bourguignon.jpg</image> </menuItem> <menuItem> <title>Cassoulet</title> <summary>Meat Casserole</summary> <description>This traditional French casserole combines pork, goose, duck, served in a
simple wine sauce</description> <price>$16</price> <image>Cassoulet.jpg</image> </menuItem> <menuItem> <title>Coq au vin</title> <summary>Rooster with red wine sauce</summary> <description>Braise of chicken cooked with wine, lardons, mushrooms and garlic. Served
with garlic mashed potatos and green beans.</description> <price>$20</price> <image>Coq-au-vin.png</image> </menuItem> ...</Menu>
Last Update: 1/12 Page 64
Copyright (C) 2012 by David Figge. All Rights Reserved.
Questions
Any questions on Linq and its uses?
Last Update: 1/12 Page 65
Copyright (C) 2012 by David Figge. All Rights Reserved.
Final Exercise
Last Update: 1/12
We will use the remaining time to get a head start on your final exercise.
Page 66
Good Luck!
Copyright (C) 2012 by David Figge. All Rights Reserved.
Advanced Web Development using C#
End of Session 3
Last Update: 1/12 Page 67