Upload
ophelia-booth
View
226
Download
0
Embed Size (px)
Citation preview
7
Session 5.2
Using LINQ to read structured data
Windows Phone
Topics Structured data and LINQ Databases and objects Database queries and LINQ Creating Silverlight layout templates Databinding to lists Using LINQ queries to produce object
collections
Windows Phone3
Reading Twitter XML feeds We can use a
WebClient request to read structured data from a web host
The Twitter feed information can be supplied as an XML structured data file
Our program must pull out some content and display it
Windows Phone4
Reading the Twitter feed
This code will fetch the XML that describes a Twitter feed
The URL contains the Twitter username
private void loadButton_Click(object sender, RoutedEventArgs e){ string url = "http://twitter.com/statuses/user_timeline/" + nameTextBox.Text + ".xml";
client.DownloadStringAsync(new Uri(url));}
Windows Phone5
XML structured data We have already seen XML in the
markup language used by Silverlight to describe pages
The XML for a Twitter feed contains elements and properties which are formatted to describe Twitter post information
We could write some C# to decode the feed, but we are going to use LINQ instead
LINQ stands for Language INtegrated Query
Windows Phone6
LINQ LINQ is a technology that is part of
the .NET system libraries It builds on C# language features to
provide easy data transfer between structured data storage and the object models used by modern languages
It is well worth knowing about
Windows Phone7
A diversion into databases If you want to store large amounts of
structured data you will not write a system to do this
Instead you will use a database The database manages the data for
you, and your program will send commands to it to add, remove and search for data
Windows Phone8
A simple Database
We can start by considering a simple sales database
This is the customer table Each row describes a single customer
Name Address Bank Details Customer ID
Rob 18 Pussycat MewsNut East Bank 123456
Jim 10 Motor Drive Big Fall Bank 654322
Ethel 4 Funny Address Strange bank 111111
Windows Phone9
Two other tablesSales tableCustomer ID Product ID Order Date Status
123456 1001 21/10/2010 Shipped
111111 1002 10/10/2010 Shipped
654322 1003 01/09/2010 On order
Product ID Product Name Supplier Price
1001 Windows Phone 7 Microsoft 200
1002 Cheese grater
Cheese Industries 2
1003 Boat hook John’s Dockyard 20
Product Table
Windows Phone10
Using the database We can combine the information in
the tables to obtain transaction details Rob has Customer ID 123456 Customer ID 123456 ordered product
ID1001 1001 is the product ID of a Windows
Phone Rob bought a Windows Phone We get the database to do this for us
by issuing queries to it
Windows Phone11
Database queries
This SQL query will create a table that contains all the orders placed by Rob
This result can then be used as the basis of another query
Database queries are much easier to create than the equivalent program statements to work through the data
SELECT * FROM Orders WHERE CustomerID = "123456"
Windows Phone12
A C# sales database
If we wrote a C# program to store the sales database our starting point would be class designs
The above class holds Customer information
public class Customer{ public string Name {get; set;} public string Address { get; set; } string BankDetails { get; set; } public int ID { get; set; }}
Windows Phone13
Holding multiple Customers
Once we have a class that contains the required data we can create collections of that object
Above we have created a list of customers
We can then store customers in the list by adding them to it
List<Customer> Customers = new List<Customer>();
Windows Phone14
Searching for customers
This is the C# code that implements the SQL query we saw earlier
public List<Order> FindCustomerOrders(int CustomerID){ List<Order> result = new List<Order>(); foreach ( Order order in Orders ) { if (order.CustomerID == CustomerID) { result.Add(order); } } return result;}
Windows Phone15
Databases and objects If object-oriented programs and
databases are to work together we need something to convert from database tables to objects and back
We can do this by creating of “glue” code that creates objects and stores them back in tables
However, this task is made much easier by LINQ
Windows Phone16
A LINQ query
This is the LINQ code that implements the SQL query we saw earlier
It does not look like legal program statements, but it compiles perfectly
It is worth a closer look
var orderQueryResult = from order in db.Orders where order.CustomerID == "123456" select order;
Windows Phone17
Query result
The query returns a result which is given the type var var means “a type which works here” The type of a var variable depends on
the context of the declaration In this case orderQueryResult will
hold a collection of var objects that look like orders
var orderQueryResult = from order in db.Orders where order.CustomerID == "123456" select order;
Windows Phone18
Iteration source
This sets up the iteration through the elements in a table
The db variable represents the database connection and we are using the Orders table from that database
var orderQueryResult = from order in db.Orders where order.CustomerID == "123456" select order;
Windows Phone19
Restriction operation
This is the restriction operation that identifies the orders to be selected from the table
In this case we are looking for orders with the CustomerID of 123456
var orderQueryResult = from order in db.Orders where order.CustomerID == "123456" select order;
Windows Phone20
Selection operation
This identifies the item to be selected and added to the result when the restriction operation succeeds
This means that we will get a collection of var results that look like order objects
We can then use these objects in our program
var orderQueryResult = from order in db.Orders where order.CustomerID == "123456" select order;
Windows Phone21
Databases on Windows Phone LINQ is a great way to combine object oriented code and databases
Unfortunately the present version of Windows Phone does not have database support
But it does contain the LINQ libraries This would seem a strange design
choice Fortunately LINQ can also be used to
read structured data and create objects from it
Windows Phone22
Twitter XML
This is an abridged Twitter status XML file
<?xml version="1.0" encoding="UTF-8"?><statuses type="array"><status> <created_at>Tue Oct 12 11:57:37 +0000 2010</created_at> <text> Hello from Twitter.</text> <user> <id>2479801</id> <name>Rob Miles</name> <profile_background_image_url> http://s.twimg.com/a/1286/images/themes/theme1/bg.png </profile_background_image_url> </user></status></statuses>
Windows Phone23
Performing the query
The first thing we need to do is get LINQ to create a LINQ XML element or XElement
We will be able to perform LINQ operations on the XElement value as if it was a database source
The Parse method works through the XML data string returned by the server
XElement TwitterElement = XElement.Parse(twitterText);
Windows Phone24
Creating the display objects We now have an easy way that we
can use LINQ to pull the required data out of the XML feed
We want to obtain and display The text of the Twitter post The data of the post The image of the Twitter user
Once we have these values we need to display them
Windows Phone25
Creating a display class
This the class that we will actually use to display a post on the screen
We will use Silverlight data binding to connect these properties to display elements
public class TwitterPost { public string PostText { get; set; }
public string DatePosted { get; set; }
public string UserImage { get; set; }}
Windows Phone26
Using LINQ to create the display
This is the LINQ query that will work through the status elements in the XML and create new TwitterPost instances from each status entry
var postList = from tweet in twitterElements.Descendants("status") select new TwitterPost { UserImage = tweet.Element("user"). Element("profile_image_url").Value, PostText = tweet.Element("text").Value, DatePosted = tweet.Element("created_at").Value };
Windows Phone27
Using LINQ to create the display
There is no restriction part as we want all the status elements
We could add one if we wanted to select particular ones based on a criteria
var postList = from tweet in twitterElements.Descendants("status") select new TwitterPost { UserImage = tweet.Element("user"). Element("profile_image_url").Value, PostText = tweet.Element("text").Value, DatePosted = tweet.Element("created_at").Value };
Windows Phone28
Finding XML elements
The Element method locates an element with a particular name
It can be used on the element it returns This is how we get the profile image
var postList = from tweet in twitterElements.Descendants("status") select new TwitterPost { UserImage = tweet.Element("user"). Element("profile_image_url").Value, PostText = tweet.Element("text").Value, DatePosted = tweet.Element("created_at").Value };
Windows Phone29
The postList variable The postList variable is a var type
This means that it will be set to the result of an operation that will build the type when it is used
In fact postList refers to a list of TwitterPost values
Now we need to get that list onto the Phone display
Windows Phone30
XAML templates What we really want to do is bind our
list of Twitter posts to some kind of list on the phone
It turns out that this is very easy to do
We can create a list template that describes the layout of some Silverlight elements that can be bound to properties in the TwitterPost class
Windows Phone31
What the display will look like
I want each twitter post to look like this
A picture on the left hand side, with the post date and content arranged to the right of this
We can use the Silverlight StackPanel element to lay this out for us
Windows Phone32
Outer StackPanel
The outer stack panel lays out elements across the list element
<StackPanel Orientation="Horizontal" Height="132"> <Image Source="{Binding UserImage}" Height="73" Width="73" VerticalAlignment="Top" /> <StackPanel Width="370"> <TextBlock Text="{Binding DatePosted}" Foreground="#FFC8AB14" FontSize="22" /> <TextBlock Text="{Binding PostText}" TextWrapping="Wrap" FontSize="24" /> </StackPanel></StackPanel>
Windows Phone33
Horizontal Stack Panel
There are two elements in the horizontal stack panel One is the image of the Twitter user The other will contain the date and the
post text
Windows Phone34
User Image
This is the image of the Twitter user The source property gives the url of
the image to be displayed
<StackPanel Orientation="Horizontal" Height="132"> <Image Source="{Binding UserImage}" Height="73" Width="73" VerticalAlignment="Top" /> <StackPanel Width="370"> <TextBlock Text="{Binding DatePosted}" Foreground="#FFC8AB14" FontSize="22" /> <TextBlock Text="{Binding PostText}" TextWrapping="Wrap" FontSize="24" /> </StackPanel></StackPanel>
Windows Phone35
Post details
The second element is another Stack Panel
This contains the post date above the post text
<StackPanel Orientation="Horizontal" Height="132"> <Image Source="{Binding UserImage}" Height="73" Width="73" VerticalAlignment="Top" /> <StackPanel Width="370"> <TextBlock Text="{Binding DatePosted}" Foreground="#FFC8AB14" FontSize="22" /> <TextBlock Text="{Binding PostText}" TextWrapping="Wrap" FontSize="24" /> </StackPanel></StackPanel>
Windows Phone36
Post details
This is the date posted element It binds to the DatePosted property in
a TwitterPost value
<StackPanel Orientation="Horizontal" Height="132"> <Image Source="{Binding UserImage}" Height="73" Width="73" VerticalAlignment="Top" /> <StackPanel Width="370"> <TextBlock Text="{Binding DatePosted}" Foreground="#FFC8AB14" FontSize="22" /> <TextBlock Text="{Binding PostText}" TextWrapping="Wrap" FontSize="24" /> </StackPanel></StackPanel>
Windows Phone37
Post text
This is the post text itself This is set to wrap around the text
area
<StackPanel Orientation="Horizontal" Height="132"> <Image Source="{Binding UserImage}" Height="73" Width="73" VerticalAlignment="Top" /> <StackPanel Width="370"> <TextBlock Text="{Binding DatePosted}" Foreground="#FFC8AB14" FontSize="22" /> <TextBlock Text="{Binding PostText}" TextWrapping="Wrap" FontSize="24" /> </StackPanel></StackPanel>
Windows Phone38
StackPanel A StackPanel will automatically
arrange the items that are placed within it
We have seen that we can place one StackPanel value inside another
They allow you to create layouts that position themselves automatically
Windows Phone39
<ListBox Height="442" HorizontalAlignment="Left" Name="tweetsListBox" VerticalAlignment="Top" Width="468"> <ListBox.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal" Height="132"> <Image Source="{Binding UserImage}" Height="73"
Width="73" VerticalAlignment="Top" /> <StackPanel Width="370"> <TextBlock Text="{Binding DatePosted}" Foreground="#FFC8AB14" FontSize="22" /> <TextBlock Text="{Binding PostText}" TextWrapping="Wrap" FontSize="24" /> </StackPanel> </StackPanel> </DataTemplate> </ListBox.ItemTemplate></ListBox>
The Complete ListBox template
Windows Phone40
<ListBox Height="442" HorizontalAlignment="Left" Name="tweetsListBox" VerticalAlignment="Top" Width="468"> <ListBox.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal" Height="132"> <Image Source="{Binding UserImage}" Height="73"
Width="73" VerticalAlignment="Top" /> <StackPanel Width="370"> <TextBlock Text="{Binding DatePosted}" Foreground="#FFC8AB14" FontSize="22" /> <TextBlock Text="{Binding PostText}" TextWrapping="Wrap" FontSize="24" /> </StackPanel> </StackPanel> </DataTemplate> </ListBox.ItemTemplate></ListBox>
A ListBox display template
The ListBox is called tweetsListbox
Windows Phone41
<ListBox Height="442" HorizontalAlignment="Left" Name="tweetsListBox" VerticalAlignment="Top" Width="468"> <ListBox.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal" Height="132"> <Image Source="{Binding UserImage}" Height="73"
Width="73" VerticalAlignment="Top" /> <StackPanel Width="370"> <TextBlock Text="{Binding DatePosted}" Foreground="#FFC8AB14" FontSize="22" /> <TextBlock Text="{Binding PostText}" TextWrapping="Wrap" FontSize="24" /> </StackPanel> </StackPanel> </DataTemplate> </ListBox.ItemTemplate></ListBox>
A ListBox display template
It contains an item template for each list item the box is going to display
Windows Phone42
<ListBox Height="442" HorizontalAlignment="Left" Name="tweetsListBox" VerticalAlignment="Top" Width="468"> <ListBox.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal" Height="132"> <Image Source="{Binding UserImage}" Height="73"
Width="73" VerticalAlignment="Top" /> <StackPanel Width="370"> <TextBlock Text="{Binding DatePosted}" Foreground="#FFC8AB14" FontSize="22" /> <TextBlock Text="{Binding PostText}" TextWrapping="Wrap" FontSize="24" /> </StackPanel> </StackPanel> </DataTemplate> </ListBox.ItemTemplate></ListBox>
A ListBox display template
This is the StackPanel we created earlier
Windows Phone43
Putting it all together Now we have a ListBox template for
the dislay that will lay out the tweets the way that we want them to appear
The next thing is to connect the ListBox to a datasource that contains a collection of TwitterPost objects for display
First we can take a look at how such a list could be made
Windows Phone44
TwitterPost p1 = new TwitterPost{ DatePosted = "Tue Oct 12 11:57:37 +0000 2010", UserImage = http://a3.twimg.com/1501/me2_normal.jpg", PostText = "This is a test post from Rob"};
TwitterPost p2 = new TwitterPost{ DatePosted = "Wed Oct 13 14:21:04 +0000 2010", UserImage = http://a3.twimg.com/1501/me2_normal.jpg", PostText = "This is another test post from Rob"};
List<TwitterPost> posts = new List<TwitterPost>();posts.Add(p1);posts.Add(p2);
Displaying Lists of Tweets
Windows Phone45
TwitterPost p1 = new TwitterPost{ DatePosted = "Tue Oct 12 11:57:37 +0000 2010", UserImage = http://a3.twimg.com/1501/me2_normal.jpg", PostText = "This is a test post from Rob"};
TwitterPost p2 = new TwitterPost{ DatePosted = "Wed Oct 13 14:21:04 +0000 2010", UserImage = http://a3.twimg.com/1501/me2_normal.jpg", PostText = "This is another test post from Rob"};
List<TwitterPost> posts = new List<TwitterPost>();posts.Add(p1);posts.Add(p2);
Displaying Lists of Tweets
This code creates two TwitterPost instances
Windows Phone46
TwitterPost p1 = new TwitterPost{ DatePosted = "Tue Oct 12 11:57:37 +0000 2010", UserImage = http://a3.twimg.com/1501/me2_normal.jpg", PostText = "This is a test post from Rob"};
TwitterPost p2 = new TwitterPost{ DatePosted = "Wed Oct 13 14:21:04 +0000 2010", UserImage = http://a3.twimg.com/1501/me2_normal.jpg", PostText = "This is another test post from Rob"};
List<TwitterPost> posts = new List<TwitterPost>();posts.Add(p1);posts.Add(p2);
Displaying Lists of Tweets
These are then added to a list of posts
Windows Phone47
Binding an XML data source
This sets the ItemSource property of the tweetsListBox to the collection of posts that we just created
Data binding will do the rest for us
tweetsListBox.ItemsSource = posts;
Windows Phone48
Binding to the twitter data
To see the posts loaded from the Twitter feed we use the list created by the LINQ query
The list will expand to fill the display and provide scrolling support if you want to view the rest of the items
tweetsListBox.ItemsSource = postList;
Windows Phone49
Demo 1: Twitter viewer
Demo
Windows Phone50
Review Web requests can return structured
data in XML format The Language Integrated Query
(LINQ) tools provide a way of converting structured data into objects
LINQ can decode an XML document and create objects with data properties
Collections of objects can be bound to Silverlight lists which contain display templates