Showing posts with label LINQ. Show all posts
Showing posts with label LINQ. Show all posts

Thursday, May 7, 2015

Simple Lambda Expressions in C#

Intro

I'm not going to go too in-depth regarding Lambda expressions or how to use them in .Net. Rather, I will just show you a short sample to whet your appetite. If you've already used lambda expressions or LINQ then this post might not teach you much, but it's a short post so suffer through it if you can :)



Code samples are in VS2013, .Net 4.5. Other environments might work just fine too.

Example


using System;
using System.Collections.Generic;
using System.Linq;

namespace BlogLambda
{
    public class SomeClass
    {
        public int ANum;
        public string AString;

        public override string ToString()
        {
            return "(" + AString + ":" + ANum + ")";
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var things = new List<SomeClass>();
            things.Add(new SomeClass() { ANum = 2, AString = "cheese" });
            things.Add(new SomeClass() { ANum = 1, AString = "bacon" });
            things.Add(new SomeClass() { ANum = 7, AString = "tires" });
            things.Add(new SomeClass() { ANum = 4, AString = "apples" });
            var orderedThings1 = things.OrderBy(t => t.ANum);
            orderedThings1.ToList().ForEach(thing => Console.Write(thing));
            Console.WriteLine("---");
            var orderedThings2 = things.OrderBy(t => t.AString);
            orderedThings2.ToList().ForEach(thing => Console.Write(thing));
            Console.WriteLine("---");
            Console.ReadKey();
        }
    }
}


As promised, a pretty small sample. First we declare a new class called SomeClass. It's got 2 fields, and int and a string. It's got a single ToString method that we'll use just to illustrate what's going on.

The real meat here is within the Main() method (as you may have guessed, this is a console application). We first create a new list of objects of type SomeClass and initialize it with 4 new instances. Things get interesting on line 27, where we have our first lambda expression. The OrderBy method lets us sort the things object by whatever we tell it to sort. In this case we're sorting on the ANum property. If you haven't seen lambdas before the syntax might look a little weird. To me it helps if i think of "things.OrderBy(t => t.ANum)" meaning "sort things by t such that t.ANum". Basically I pretend that " => " means "such that". It's not always a great way to conceptualize, but it's helped me.

Moving on, you can see that we then output the list (notice the cool use of the ForEach extension method which allows us to spit out the whole list to the console, with a single line of code). We then sort the list a 2nd time on the AString field and send the output to the console once again. Here's the output:

(bacon:1)(cheese:2)(apples:4)(tires:7)---
(apples:4)(bacon:1)(cheese:2)(tires:7)---

That's all there is to it! First list sorted by ANum, second list sorted by AString.

What's Next?

Lambda expressions can get way more useful and way more complicated. I've barely even slightly rubbed the surface, much less scratched it. Read up on them! If you haven't tried LINQ yet, jump into that too. It can be a great time saver for us coder types.

Resources

dotnetperls Lambda

Thursday, July 24, 2014

NoSQL - MongoDB; Querying Data

Intro

In Part 1 of the series on NoSQL we were introduced to some of the general concepts behind this movement and how some of the technologies work in a general sense. In Part 2 we setup a MongoDB instance and wrote some C# code to insert data into the DB. Here in the final installment of the series we'll cover getting our data back out of the MongoDB instance.

To the Code!

Let's jump on into some code. Open back up the solution file you created back in Part 2, BlogMongo. If you named your stuff the same I did, you can open up default.aspx and default.aspx.cs also as that's where we'll put our code. I'm adding a new button to the form called btnQuery and giving it a new click event, which I'll leave empty for the moment. Now, do you remember this function from last week?

        private MongoCollection GetMongoCollection()
        {
            var client = new MongoClient("mongodb://localhost");
            var server = client.GetServer();
            var database = server.GetDatabase("BlogMongo");
            return database.GetCollection<Stuff>("stuffses");
        }


This is the function we used last week to connect to our database and our collection (table), using the Mongo C# driver. Now let's pull some data out of it; you'll be surprised just how easy this is:

        
        private void QueryStuff()
        {
            var collection = GetMongoCollection();
            var singleQuery = Query<Stuff>.EQ(e => e.SomeInt, 3);
            var stuff = collection.FindOneAs<Stuff>(singleQuery);
            var serializer = new JavaScriptSerializer();
            Response.Write(serializer.Serialize(stuff));
        }


This method pulls a single document/object out of the database and collection and spits it out in the response. The first line of the method just opens up a connection to the database and retrieves a reference to our collection. The second line creates a Mongo query object (you'll have to add a using statement to MongoDB.Driver.Builders). The query object should return object(s) of type Stuff, and the query shall look for an item with a value of 3 for the property SomeInt. The 3rd line tells the collection to pull back a single item of type Stuff that matches the query we created in the previous line. Line 4 creates a javascript serialization object that we're just using to display some friendly output, and line 5 spits out our serialized JSON object to the browser. Yes that's right, 3 lines of code (which we could easily condense further) pulls a specific object out of the database for us. Nifty! Go ahead and call this new method in the click event of your query button so you can see the output. Just in case you're not coding along with me, here's what the output looks like:

{"Id":"d639cae8-906a-4d7c-ab6d-553319a8a70e","SomeInt":3,"SomeString":"yeah, a string","ListOfStrings":["0","1","2"]}

Ok that was some really cool stuff. Almost as cool as an iceberg hitting you in the face! But how do we create some niftier, more complicated queries? Well as it turns out, the Mongo C# driver supports quite a few LINQ operations for data querying so you can have some real fun here! Let's see another example of querying MongoDB data, this time with LINQ:

        private void QueryStuff()
        {
            var collection = GetMongoCollection();
            var singleQuery = Query<Stuff>.EQ(e => e.SomeInt, 3);
            var stuff = collection.FindOneAs<Stuff>(singleQuery);
            var serializer = new JavaScriptSerializer();
            Response.Write(serializer.Serialize(stuff));
            var linqQuery = from item in collection.AsQueryable<Stuff>()
                            where item.SomeString == "yeah, a string"
                            select item;
            foreach (var item in linqQuery)
                Response.Write(serializer.Serialize(item));
        }



Our new code starts on line 6, beneath the prior junk. Line 6 sets up our LINQ query. I'm assuming you're familiar enough with LINQ to either create LINQ queries or google around to figure out how to make them so I won't go into detail on it, but as you can see this query is meant to select all the items from our collection who have a SomeString property with the value "yeah, a string". (Note: you'll need to add 2 more using statements. MongoDB.Driver.Linq and System.Linq). The foreach below it is just our output generation code. Easy, simple, and powerful, that's the best kind of code there is! Here is the new output (note that it includes the prior line of output too, so there's 1 extra object of type Stuff here):

{"Id":"d639cae8-906a-4d7c-ab6d-553319a8a70e","SomeInt":3,"SomeString":"yeah, a string","ListOfStrings":["0","1","2"]}{"Id":"d639cae8-906a-4d7c-ab6d-553319a8a70e","SomeInt":3,"SomeString":"yeah, a string","ListOfStrings":["0","1","2"]}{"Id":"494be80b-5f1a-48c4-9a15-3c01f89d2216","SomeInt":4,"SomeString":"yeah, a string","ListOfStrings":["0","1","2","3"]}{"Id":"a089f1bd-c33b-43ae-9f25-894e0c5e31c2","SomeInt":5,"SomeString":"yeah, a string","ListOfStrings":["0","1","2","3","4"]}{"Id":"097c8d4f-fff4-4daa-a535-75d38fe87199","SomeInt":3,"SomeString":"yeah, a string","ListOfStrings":["0","1","2"]}

That's pretty much all we're going to cover folks! These are just the basics of querying a MongoDB instance, but this will get you pretty far. Here's the complete code file in case you need it:

using MongoDB.Bson;
using MongoDB.Driver;
using MongoDB.Driver.Builders;
using System;
using System.Collections.Generic;
using System.Web.Script.Serialization;
using System.Linq;
using MongoDB.Driver.Linq;

namespace BlogMongo
{
    public class Stuff
    {
        public Guid Id { get; set; }
        public int SomeInt { get; set; }
        public string SomeString { get; set; }
        public IList<string> ListOfStrings { get; set; }
        public Stuff()
        {
            ListOfStrings = new List<string>();
        }
    }

    public partial class Default : System.Web.UI.Page
    {
        private Stuff GenerateStuff()
        {
            var stuff = new Stuff() { Id = Guid.NewGuid(), SomeInt = new Random().Next(0, 10), SomeString = "yeah, a string" };
            for (int i = 0; i < stuff.SomeInt; i++)
                stuff.ListOfStrings.Add(i.ToString());
            return stuff;
        }

        private MongoCollection GetMongoCollection()
        {
            var client = new MongoClient("mongodb://localhost");
            var server = client.GetServer();
            var database = server.GetDatabase("BlogMongo");
            return database.GetCollection<Stuff>("stuffses");
        }

        private void SaveStuff()
        {
            var stuff = GenerateStuff();
            var collection = GetMongoCollection();
            collection.Save(stuff);
        }

        private void QueryStuff()
        {
            var collection = GetMongoCollection();
            var singleQuery = Query<Stuff>.EQ(e => e.SomeInt, 3);
            var stuff = collection.FindOneAs<Stuff>(singleQuery);
            var serializer = new JavaScriptSerializer();
            Response.Write(serializer.Serialize(stuff));
            var linqQuery = from item in collection.AsQueryable<Stuff>()
                            where item.SomeString == "yeah, a string"
                            select item;
            foreach (var item in linqQuery)
                Response.Write(serializer.Serialize(item));
        }

        protected void btnQuery_Click(object sender, EventArgs e)
        {
            QueryStuff();
        }

        protected void btnSave_Click(object sender, EventArgs e)
        {
            SaveStuff();
        }

    }
}


What's Next

There are plenty of other ways to query a MongoDB instance. Play around with it and see what you can find, and read the resource links below. The Mongo C# LINQ tutorial and the Mongo C# Driver Getting Started pages are both very handy. This is my last blog on NoSQL (at least for now) though, so we'll be on to a different topic next week. If you want further NoSQL knowledge, then you're on your own buddy!

Resources

MongoDB C# Driver LINQ Tutorial
MongoDB Getting Started With the C# Driver

Thursday, July 17, 2014

NoSQL - MongoDB; Setup and Saving Data

Intro

In the previous post in this series I covered the basics of NoSQL data stores. I briefly mentioned MongoDB and its home in the NoSQL world as a document store. This week I'll go over some of the basics of using MongoDB in your c# code. Hold onto yer hats folks, we're in for a ride!

Setting up Mongo Locally

Go to the MongoDB download page, download and setup the correct version of Mongo for your OS. The instructions on their site are better than anything I can write, so do what they say and you'll be fine :). Be sure to actually run the MongoDB system after you install it (there are instructions for running the program on their website too), as it's pretty tough to connect to a database that isn't running.

A Free MongoDB GUI

MongoDB does not come with a GUI. If you've got a SQL Server background you've probably become accustomed to visualizing your data using SQL Server Management Studio, as it's a very handy GUI for navigating around your data. Mongo does have a couple options, they just don't come with MongoDB. For this tutorial, I'll be using MongoVue, which I suggest you download too for your own usage. I won't get into general usage of this program as it's pretty easy and it's detailed nicely on their website.

A Quick Bit of Mongo Terminology

If you have a SQL background you're well on your way to understanding how a MongoDB server is organized. The only thing that may throw you off initially is Mongo doesn't use tables. The closes thing they have is a Collection, which is roughly akin to a table. You're supposed to store only a single type of object within each collection, though it's not enforced. Still, it's a good idea as it keeps your data organized.

Saving Data

OK then cool cats, it's time to fire up Visual Studio and play with Mongo. Create yourself a new webforms project. I called mine BlogMongo, but call yours whatever you like. Now go into NuGet package manager and install the package "mongocsharpdriver" into your project. This NuGet package contains everything you need to read and write data using MongoDB and C#. It's the official package listed on the MongoDB site, so it's my preferred option though there are others out there.

Drop a server-side button on your webform.Call the button btnSave. Add a click() event to it.Add a couple using statements too; one for MongoDB.Bson and one for MongoDB.Driver. Now I'll work a little coding magic, paste it in here, and discuss below:

using MongoDB.Bson;
using MongoDB.Driver;
using System;
using System.Collections.Generic;

namespace BlogMongo
{
    public class Stuff
    {
        public Guid Id { get; set; }
        public int SomeInt { get; set; }
        public string SomeString { get; set; }
        public IList<string> ListOfStrings { get; set; }
        public Stuff()
        {
            ListOfStrings = new List<string>();
        }
    }

    public partial class Default : System.Web.UI.Page
    {
        private Stuff GenerateStuff()
        {
            var stuff = new Stuff() { Id = Guid.NewGuid(), SomeInt = new Random().Next(0, 10), SomeString = "yeah, a string" };
            for (int i = 0; i < stuff.SomeInt; i++)
                stuff.ListOfStrings.Add(i.ToString());
            return stuff;
        }

        private MongoCollection GetMongoCollection()
        {
            var client = new MongoClient("mongodb://localhost");
            var server = client.GetServer();
            var database = server.GetDatabase("BlogMongo");
            return database.GetCollection<Stuff>("stuffses");
        }

        private void SaveStuff()
        {
            var stuff = GenerateStuff();
            var collection = GetMongoCollection();
            collection.Save(stuff);
        }

        protected void btnSave_Click(object sender, EventArgs e)
        {
            SaveStuff();
        }

        protected void Page_Load(object sender, EventArgs e)
        {
        }
    }
}



You'll see after the using statements, the first thing we've done is add a class called Stuff. This is just our POCO (plain old CLR object) that we'll store in the database. The GenerateStuff() method within our page merely creates an object of type Stuff and puts some data in it.

GetMongoCollection() is where things start to get interesting. The first line in the function gets us a reference to an MongoClient object, which is how you connect to a Mongo database. The code is connecting to the local installation we did up above. Line 2 of the method gets a reference to the Mongo server. In this case it's the same machine, but hey we need an object. Line 3 gets a reference to a database named BlogMongo within the Mongo server. Those of you reading carefully might be thinking "uh...Pete, forget something? Like maybe creating the database?". Nay friends, nay! I forgot no such thing! Call it a feature or call it a piece of kryptonite, but Mongo will create a database automatically the first time you save some data into it. So, even though this database doesn't yet exist, we can reference it. Neato! Line 4 retrieves from the database a collection (or table if you'd rather) named stuffses. Note that this collection doesn't exist yet either; the same rule for database creation applies to collection creation.

The next interesting method is SaveStuff(). It's pretty compact at 3 lines, and the 3rd line is the only really new bit of awesome. This uses our collection reference that we created above and calls its Save() method in order to save our stuff object which is of type Stuff. The Save() method is used for an upsert. There are separate Insert() and Update() methods, but I prefer to use this multipurpose method.

Now, just to prove the magic is still alive in my relationship with the code, I ran this little fella and clicked the button 4 times. Here is the representation of our data in MongoVUE:


A quick note on the storage behind MongoDB: MongoDB stores its data in BSON format, which is Binary JSON. It's just a flavor of JSON with a little bit of extra bells and whistles. That's why, in the above screenshot of MongoVue, I elected to show you the JSON representation of our stored objects. JSON is a pretty universal communication mechanism these days, so getting used to seeing it an using it can only benefit you.

Ok one last quick note, then I'm done noting. Really: See how there is no field named Id in my stored objects in that MongoVue screenshot, even though there is a field in the class Stuff named Id? This is because the Mongo C# driver will automatically use any field named Id as your primary key/id field, which is how documents are identified within the MongoDB database. MongoDB however stores such fields with a name of _id unless you specify otherwise, so in this case the field Id (which is a useful standard, so name your Id fields this if you can) maps to _id in the MongoDB database.

What's Next?

Next week will be the final installment of NoSQL/Mongo. I'll show you guys how to query data. Maybe a few other tricks too if I have the time and we have enough space on the blog post.

I encourage you to read up on using the Mongo C# driver using the link in the resources section below.We only scratched the surface this week, and we'll lightly gouge it next week. There's still plenty we won't have time for though, so if you like MongoDB and you want to learn more, their website is the best place to get into it.

Resources

MongoDB-Getting Started With the C# Driver

Thursday, June 12, 2014

LINQ - LINQ to SQL

Intro w/Recap

In part 1, part 2, and part 3 we discussed LINQ basics, some more advanced techniques for dealing with objects in LINQ, and LINQ to XML. Here in our final post of the series we'll discuss LINQ to SQL, and briefly discuss Entity Framework in order to give some context to LINQ to SQL. What is LINQ to SQL? As you can guess, it is the usage of LINQ with data stored in a sql-compatible database such as MS SQL Server. For the purposes of our discussion we will be using SQL Express 2008 R2, though these samples will work fine with newer versions as well.

Entity Framework Basics

At this point hopefully you're wondering why I plan on discussing Entity Framework (EF). The reason is that LINQ to SQL works directly with Entity Framework objects. Entity Framework is MS's Object Relational Mapper (ORM) that helps save you time by linking your Plain-Old-CLR-Objects (POCO's) to your database. If you've ever had to link objects with database tables/fields you know it can be very tedious and time-consuming work, and ORM's help automate much of this tedium.

As part of today's LINQ lesson I'll walk you through how to get a database all setup and ready to map with EF, then I'll show you how to have EF automatically create your tables/fields based on object(s) that you've created in code.

Let's start with setting up the database. If you don't already have it, go download sql server express edition. You can find it here. Install that little sucker (get the one called "SQL Server Express With Tools") and then return. If you need help with installation, please post a reply here in the blog so that everyone can benefit from the shared knowledge. After you have completed installation, you're done! Yeah EF is so cool that it creates your database, tables, and columns for you. Can't get much easier than that. But hey we haven't done that yet so keep reading.

Code-First DB Setup w/EF

That's it for the database for now. We're going to use something called code-first setup of our EF, meaning we'll write our storage classes first and we'll use some spiffery to automatically create the tables for us.

I've created a couple classes myself for storage; Animal and Show. Here is the code for both:

using System.ComponentModel.DataAnnotations;
namespace BlogLinq
{
    public class Animal
    {
        [Key]
        public string name { get; set; }
        public string animalType { get; set; }
    }
}


using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;

namespace BlogLinq
{
    public class Show
    {
        [Key]
        public string name { get; set; }
        public virtual List<Animal> animals { get; set; }
    }
}

As you can see, we have an Animal with 2 properties (name and animalType), and a Show with 2 properties (name and animals, which is a list of type Animal). We use the Key attribute to denote which field is the primary key for our class/table, so that EF can avoid creating a heap table. Trust me (or ask Bobby, my resident DBA, they're bad). The only other oddity here is that I made the animals property of the Show class virtual. This is necessary for EF to load such a list at runtime from a SQL data source.

Next you need to install the EntityFramework package from NuGet. If you don't, your code won't compile as that namespace and the Key attribute I used above are from EF. I'm assuming you know how to work with NuGet package manager, but if that's not the case feel free to ask in the comments below. Now you need to create a "Context" class, which is just a fancy way of saying that you need something that ties LINQ to your database table(s) and classes. Create a class called ZooContext. Here's the code of my ZooContext:

using System.Data.Entity;

namespace BlogLinq
{
    public class ZooContext : DbContext
    {
        public DbSet<Show> Shows { get; set; }
        public DbSet<Animal> Animals { get; set; }
    }
}

Because this blog post isn't about EntityFramework (let me know if you want to see such a beast!) I won't go into any further detail on this ZooContext class, so we'll just say for now that this class as defined above will let us use LINQ to query the database rather than having to roll our own SQL queries.



Inserting Data With EF

What fun is querying data when there's no data? none at all! We're going to write a quick method here that will insert data into our database and tables for us. "But Pete", you say, "We don't have a database, or tables, or columns!". Yeah I know that, and so does EF. Trust me, it will create this crap for you. Write a function like this:

        protected void btnEFInsert_Click(object sender, EventArgs e)
        {
            var zooContext = new ZooContext();
            var show = new Show() { name = "Early", animals = new List<Animal>() };
            show.animals.Add(new Animal() { animalType = "Bird", name = "George" });
            var show2 = new Show() { name = "Late", animals = new List<Animal>() };
            show2.animals.Add(new Animal() { animalType = "Ferret", name = "Fred" });
            show2.animals.Add(new Animal() { animalType = "Bear", name = "Bear" });
            zooContext.Shows.Add(show);
            zooContext.Shows.Add(show2);
            zooContext.SaveChanges();
        }



In the first line of our function we create an instance of our ZooContext class that links EF to our POCO's. We then proceed to create some shows, add animals to them, and add our shows (which contain the animals) to the zooContext. Then we call zooContext.SaveChanges(), and voila! EF created a database for us, a few tables, setup our columns, and even created primary and foreign keys for us. That's so darn cool I could pinch myself. Here's a screenshot full of awesomesauce:



Querying Data With LINQ to SQL

Back to LINQ...now that we have a little bit of data in our database our foray into pure EF is over, so let's query that data using LINQ. This should look pretty familiar by now:

        protected void btnLinqSqlSelect_Click(object sender, EventArgs e)
        {
            var zooContext = new ZooContext();
            var query = from show in zooContext.Shows
                        where show.name.Equals("Late", StringComparison.OrdinalIgnoreCase)
                        select show;
            foreach (var show in query)
            {
                Response.Write("show: " + show.name);
                foreach (var animal in show.animals)
                    Response.Write(String.Format("<br / >    {0} the {1} is in the {2} show!", animal.name, animal.animalType, show.name));
            }
        }



We start by creating a ZooContext object in order to pull junk from the database, then it's all just standard-looking LINQ from there. In the above LINQ query we retrieve all the shows (there's just 1) named "Late", and EF/LINQ goes and pulls all the shows and their child animals from the database for us. Simple and powerful stuff here!

Here's the output in case you don't trust me about the code working:
show: Late
    Bear the Bear is in the Late show!
    Fred the Ferret is in the Late show!




Drawbacks

With great power comes great headaches. The cool time-saving and readability afforded by LINQ comes with a price. Ask your local DBA what they think about ORM's and you'll get a good first-person ear-blasting about the evils of auto-generated queries. Fine-tuning a SQL database really is a profession unto itself, which is part of why the DBA was invented. EF and LINQ generate some decent SQL, but in many cases it's not optimized. This isn't much of a concern with small apps, but if you expect to scale, dig further into LINQ/EF and see what all options you can find for optimization.


What's Next?

  • You could spend some time cozying up to Entity Framework. Learn things like changing the name of the database your data gets plopped in, view the sql queries it generates (it's still using sql behind the scenes), how to add new fields to your classes and have them added to the table(s), etc.

Resources

My Code (Created Using VS Express 2013)!
Entity Framework
SQL Express

Thursday, June 5, 2014

LINQ - LINQ to XML

Intro


This week we'll build on the foundation we learned in part 1 and part 2, adding LINQ to XML to our repertoire. As you have probably surmised, LINQ to XML technology lets you use the LINQ query syntax, with which you've now familiarized yourself, to query data from an in-memory representation of XML data. To an extent, this frees you from learning even more technology for XML parsing such as XPath, so you can have a common framework of knowledge (LINQ) to query many different types of things (objects, XML, and next week SQL data). Perhaps I should have stated and emphasized this better up-front in part 1 to drum up more interest in LINQ, but learning LINQ is almost like a 3-for-1 deal. You learn LINQ, and you get to query 3 types of data. It saves code and saves time, and what else can you ask for in the world of coding? No it won't write your code for you. I know you were gonna ask :)

Loading XML

Step 1 in our journey today is loading an XML string from memory. There are other ways to get XML into a LINQ to XML object such as loading from disk, creating the xml object tree ourselves, etc, but this is the simplest. Note that you'll need to add System.Xml.Linq to your using clause. Here is how to load XML from a string:

private XElement ZooXml
        {
            get 
            {
                return XElement.Parse("<zoo><show name='Early'><animal name='Simba' animalType='lion'></animal><animal name='Bill' animalType='baboon'></animal></show><show name='Lunch'><animal name='Bjork' animalType='baboon'>Bjork says bye!</animal></show><show name='Evening'><animal name='Pete' animalType='panda'></animal></show></zoo>");
            }
        }



The only thing noteworthy here is XElement.Parse. XElement is the class you'll work with most frequently in LINQ to XML as it represents an XML element. The parse method parses the string that you pass in and returns a new object of type XElement. Pretty simple stuff so far.


Querying Basic Data

I know you all paid the price of admission to see the real show, so let's start querying the data. What I want is to pull a list of all the shows and display the names of all the shows. Here's our first example:

        protected void btnLinqXmlMultipleElements_Click(object sender, EventArgs e)
        {
            XElement zooElement = ZooXml;
            var shows = from show in zooElement.Elements("show")
                        select show;
            foreach (var show in shows)
                Response.Write("< br />" + show.Attribute("name").Value);
        }


and here's the output:
Early
Lunch
Evening

Pretty simple code huh? The .Elements() method will return all matching elements of the specified element/node (in this case zooElement, which is the root element). We specify that we only want elements named show in this case, so we only get back show elements. Then we loop through the result set and display the name of each show.

Elements Containing Specific Sub-Elements

What if we wanted only shows that have a baboon in them?

        protected void btnLinqXmlShowsWithBaboons_Click(object sender, EventArgs e)
        {
            XElement zooElement = ZooXml;
            var shows = from show in zooElement.Elements("show")
                        where show.Elements("animal").Any(animal => animal.Attribute("animalType").Value.Equals("baboon", StringComparison.OrdinalIgnoreCase))
                        select show;
            foreach (var show in shows)
                Response.Write("< br />" + show.Attribute("name").Value);
        }



And our output (hey, it's even correct!) is as follows:
Early
Lunch

As you can see above, the where clause is what's different. We tell the compiler that we want all show elements who contain an element named "animal" which have an attribute "animalType" with the value "baboon". There's nothing complicated here, with a little practice you can get the hang of it quite easily.

Getting Element Value(s)

Scroll back up near the top for a moment where we defined the property ZooXml. Notice how Bjork the baboon has a value within her xml element, with the value "Bjork says bye!"? Putting values into xml tags is common so let's see filter on and use them:

        protected void btnLinqXmlElementWithValue_Click(object sender, EventArgs e)
        {
            XElement zooElement = ZooXml;
            var elements = from element in zooElement.Descendants()
                            where !String.IsNullOrWhiteSpace(element.Value) && element.Name.ToString().Equals("animal", StringComparison.OrdinalIgnoreCase)
                            select element;
            foreach (var element in elements)
                Response.Write("< br />" + element.Name + "::" + element.Attribute("animalType").Value + "::" + element.Attribute("name").Value + "::" + element.Value);
        }



Output:
animal::baboon::Bjork::Bjork says bye! 

The first thing you'll notice different is that we used Descendants() this time instead of Elements(). What's the diff yo? Elements are just the direct children of where we're looking. For our prior queries that was good enough. For this query, we know that an animal is what has a value, and an animal is not a direct child of the root zoo element. Rather, animals are children of the show in which they perform, so we need to use the Descendants method().

The next difference is our use of element.Value. This isn't voodoo or anything, it's exactly what you think; the element value. We use it in our where clause to pull only those elements that have a value.

What's Next?

There are lots more things that you can do with LINQ to XML. We don't have time to cover all of them, but take a look on MSDN; there's lots to read.
  • Other methods such as Ancestors(), ElementsAfterSelf(), etc.
  • XNode: look it up! It's powerful. Finer level of detail than XElement, though you won't often need it's functionality.
  • Manipulate and save XML.
  • Create an XML tree entirely in code.
  • Peek ahead to LINQ to SQL which will be next week's post.
  • Experiment with last week's topics while playing with LINQ to XML. Joins, ordering, grouping, projections. This is by far the best thing you could do, as you'll put the pieces of the puzzle together and learn them as a whole.

Resources

LINQ to XML on MSDN

Wednesday, May 28, 2014

LINQ - Ordering, Grouping, Joining, and Projections

Intro


In part 1 of our series on LINQ we discussed the very basics of LINQ, pulling a few choice bits of data out of an array based on a simple filtering clause. This week we'll dive a little deeper into LINQ, exploring how to sort the results, group results, join 2 sources together to get a single output, and how to manipulate the structure of the output using projections. Hold onto yer hats (or other similar headgear such as beanies, earmuffs, etc)!

Ordering (orderby)

Everybody needs to sort data at some point in their coding career. To help illustrate my point with many of these LINQ operations, I'm going to compare using T-SQL against a fictional database in a zoo, versus using LINQ queries to pull the same data from C# objects. For starters, let's see a sample T-SQL query for pulling a list of baboons, sorted by aggressiveness:

select * 
from tblAnimals
where AnimalType = 'baboon'
order by Aggressiveness


Now let's see the same thing in LINQ using objects already loaded in memory:

        private dynamic CreateAnimal(string animalType, string name, int aggressiveness)
        {
            dynamic animal = new ExpandoObject();
            animal.AnimalType = animalType;
            animal.Name = name;
            animal.Aggressiveness = aggressiveness;
            return animal;
        }

        private List<dynamic> PopulateAnimalsList()
        {
            var animals = new List<dynamic>();
            animals.Add(CreateAnimal("lion", "Simba", 10));
            animals.Add(CreateAnimal("baboon", "Bobby", 4));
            animals.Add(CreateAnimal("baboon", "Bill", 1));
            animals.Add(CreateAnimal("baboon", "Bjork", 7));
            animals.Add(CreateAnimal("panda", "Pete", 2));
            return animals;
        }

        protected void btnLinqOrdering_Click(object sender, EventArgs e)
        {
            var animals = PopulateAnimalsList();
            var query = from animal in animals
                        where animal.AnimalType.Equals("baboon")
                        orderby animal.Aggressiveness
                        select animal;
            foreach (var val in query)
                Response.Write("<br />" + val.Name + " the " + val.AnimalType + " has aggro val of " + val.Aggressiveness);
        }


The first 2 methods are just setup, putting a list of animals into memory for us to manipulate. The LINQ-ified portion of our code is the 3rd and final method btnLinqOrdering_Click which creates the following output:
Bill the baboon has aggro val of 1
Bobby the baboon has aggro val of 4
Bjork the baboon has aggro val of 7

The orderby clause, just under the filtering where clause, is the sauce which produces this little bit of magic. By default, just like T-SQL, the sort order is ascending as you can see in the above output. If you wanted to order descending, you would change the orderby line to "orderby animal.Aggressiveness descending".
(Hey, wondering about dynamic and ExpandoObject? Keep paying attention to my blog, it'll probably make an appearance in a month or so).

Grouping (group)

Let's say you wanted to return a list of the types of animals and the count of each type. This will involve grouping. As with the last section, we'll start things with a sample bit of T-SQL:

select AnimalType, Count(1) as [NumAnimals]
from tblAnimals
group by AnimalType
order by Aggressiveness


Here were are selecting a list of types of animals and the number of each type of animal. How would we accomplish the same thing in LINQ? Here's that bit o' sample code:

        protected void btnLinqGrouping1_Click(object sender, EventArgs e)
        {
            var animals = PopulateAnimalsList();
            var query = from animal in animals
                        group animal by animal.AnimalType into animalGroup
                        select animalGroup;
            foreach (var val in query)
                Response.Write("<br /> there are " + val.Count() + " " + val.Key + "ses");
        }


This isn't the most grammatically correct output ever, but it's correct at least:
there are 1 lionses
there are 3 baboonses
there are 1 pandases

Notice how in our foreach loop where we display the output, we are accessing val.Count() and val.Key? This is because when you use the group clause in LINQ as denoted by group...by...into..., you actually create a list of lists. The outer list is a list of your groups which has a Key property that  in this case AnimalType property (because it's the "by" in the group clause).

While we do get a nice count by group from the above LINQ, we can't tell which animals belong to each group. What could we do in our code to show the contents of the groups/inner lists? the query is already selecting them, so in this case it's just a matter of changing our output. Here's the updated code:

            foreach (var val in query)
            {
                Response.Write("<br /> there are " + val.Count() + " " + val.Key + "ses");
                foreach (var animal in val)
                    Response.Write("<br />    " + animal.Name + " the " + animal.AnimalType + " has aggro val of " + animal.Aggressiveness);
            }


The output is pretty much what you'd expect:
there are 1 lionses
    Simba the lion has aggro val of 10
there are 3 baboonses
    Bobby the baboon has aggro val of 4
    Bill the baboon has aggro val of 1
    Bjork the baboon has aggro val of 7
there are 1 pandases
    Pete the panda has aggro val of 2

As you can see, I didn't lie to you earlier when I said the result of a group'd LINQ statement is a list of lists. The above code loops through the outer and inner lists, producing a combined output of summary and detail data. Spifferiferous!

Joining (join), as well as Projections

Joining lets you combine 2 source data sets into a single output data set. Let's pretend for this example that we want to see a list of which animals are in which shows. The shows are stored in a different table for T-SQL and in a different list for LINQ. Here's what the query might look like in T-SQL:

select tblShows.Name as [ShowName], tblAnimals.Name as [AnimalName]
from tblShows
join tblAnimals
on tblShows.AnimalName = tblAnimals.Name


This is pretty simplified as it assumes that the primary key of the Animal (unique property) is it's name, and it assumes only a single animal can be in any show, but hey you gotta lose realism for simplicity sometimes.

Now let's see what that might look like in LINQ:

        private dynamic CreateShow(string showName, string animalName)
        {
            dynamic show = new ExpandoObject();
            show.Name = showName;
            show.AnimalName = animalName;
            return show;
        }

        private ListPopulateShows()
        {
            var shows = new List<dynamic>();
            shows.Add(CreateShow("Early", "Simba"));
            shows.Add(CreateShow("Lunch", "Bjork"));
            shows.Add(CreateShow("Evening", "Pete"));
            return shows;
        }

        protected void btnLinqJoin_Click(object sender, EventArgs e)
        {
            var animals = PopulateAnimalsList();
            var shows = PopulateShows();
            var query = from animal in animals
                        join show in shows on animal.Name equals show.AnimalName
                        select new { ShowName = show.Name, AnimalName = animal.Name };
            foreach (var val in query)
                Response.Write("<br />the " + val.ShowName + " show has " + val.AnimalName);
        }



As in our first example, the first 2 methods are just setup. They create our lovely new list of shows. The 3rd and awesomerest method is our little bit o special LINQ. You can see we've joined the list "animals" to the list "shows", via the join clause. Notice the weird new "select new..." syntax? This is what's known as a projection. You can see the resource link at the bottom of this post for a full definition, but basically in this query our output is a list of a newly defined type of object that has 2 properties, ShowName and AnimalName. It's a pretty cool concept that you can just us a dynamic object like this for your LINQ output, it makes things very flexible. Other than that, we have what you'll recognize by now as some pretty standard output:
the Early show has Simba
the Lunch show has Bjork
the Evening show has Pete


What's Next?

I hope you enjoyed Part 2 in our series on LINQ. I learned a bit along the way myself. For the next post I'll show you guys how to use a different kind of data source, either SQL server or XML files. I haven't decided which yet. If you've read this far and have a preference, let me know in the comments and I'll take your thoughts into consideration when I make my final decision.

Resources

Basic LINQ Query Operations

Friday, May 16, 2014

LINQ - An Introduction

Intro

LINQ stands for Language Integrated Query. It was introduced with Visual Studio 2008, but it is probably still a new concept for many so I figured it just might be worth a blog on the topic. To me, LINQ is basically an extension of .Net that lets you use sql-like query syntax to retrieve some types of data. Let's say for example you have a list of customers and you want to retrieve all customers who have blue hair. If you were to do this in sql, it might look something like "select * from tblCustomers where HairColor = 'blue'". In C# you'd have to create a temp list, then write a loop where you find all blue-hairs and insert them into your temp list. It's just more work. LINQ however lets you treat some aspects of .Net as though you were using something akin to SQL.

On top of that, LINQ lets you pull data from many different types of sources. You can use LINQ to SQL to use LINQ for querying databases, you can use LINQ to XML to use link for querying XML files, and of course there's just plain old LINQ for querying lists of objects in .Net. By learning LINQ, you learn how to, in some fashion, query many different types of data so it saves you a little bit of code and a little bit of extra brainpower for learning other new things. Neat huh?

Constructing a LINQ Query

A LINQ query is comprised of 3 clauses: from, where, and select. If you're familiar with SQL syntax you'll notice that this isn't quite the same. In SQL, it's select, then from, then where. But hey, if this were the exact same order then life wouldn't be fun at all, and hippos would rule the seas. Or something. The from clause is your data source, the where clause is your filtering, and the select clause is what you're returning. Let's see a quick sample:

        protected void btnLinq1_Click(object sender, EventArgs e)
        {
            var blurbs = new string[] { "fred", "george", "fred rocks", "george doesn't" };
            var query = from blurb in blurbs
                        where blurb.StartsWith("fred")
                        select blurb;
            foreach (var val in query)
                Response.Write(" " + val);
        }


The above sample is a button click event in a webforms project. We first define our data source, which in this case is a simple array of strings named blurbs. We then construct our query object. Our query has a from clause that shows we are pulling data from blurbs, the where clause states that we only want to retrieve those blurbs who start with the word "fred", and the select clause states we are selecting individual blurbs from the list of blurbs. The last 2 lines loop through our query results (tip: the query isn't actually run until its results are used! see Introduction to LINQ Queries for more info) and write them out to the web page. As you can guess, we only retrieve and thus only display the values "fred" and "fred rocks" from the list of blurbs.

What's Next?

Either wait until next week's blog post when I delve a little deeper, or be a suck-up and read some of the resources below for more info.

Resources

LINQ
Introduction to LINQ
Introduction to LINQ Queries
Basic LINQ Query Operations