Introduction
Using LINQ to query objects and filtering data on memory. The project is done on MVC using Razor but we'll just be looking at the C# code.
Background
We usually use loops and other methods to filter objects on memory, LINQ provides us
with multiple ways of manipulating and querying these objects. I tried it a couple years
back and I'm not looking back; LINQ is specially easy to understand if you have used SQL syntax on the past.
The Solution
All the code will be available on the zip dile attached with the article.
First know that we'll be using UserInfo
objects that will have a property that is a List<Messages>
.
If you have not used the namespace System.Collections.Generic
, just keep in mind that it allows to create strong typed lists of objects. These lists are very
close to an array but since we can specify the type we don't need to cast the objects back to its original type.
ArrayList array = new ArrayList();
array.Add(new UserInfo());
UserInfo userObject = array[0] as UserInfo;
But a generic list keeps the object type and we just need to get it from the collection.
List<UserInfo> list = new List<UserInfo>();
list.Add(new UserInfo());
UserInfo userObject = list[0];
Now that we got the basics in, we'll be using these two objects:
public class UserInfo
{
public string UserID { get; set; }
public string Password { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Country { get; set; }
public string ZipCode { get; set; }
public bool Active { get; set; }
public List<Messages> Messages { get; set; }
public UserInfo()
{
Messages = new List<Messages>();
}
}
public class Message
{
public Guid MessageID { get; set; }
public string Subject { get; set; }
public string Body { get; set; }
public Message()
{
MessageID = Guid.NewGuid();
}
}
For loading some sample data we'll use this function:
List<UserInfo> users;
public void LoadSampleData()
{
users.Add(new UserInfo() { UserID = "User1", Address = "Test",
City = "Miami", State = "FL", Country = "US", Active = true });
users.Add(new UserInfo() { UserID = "John", Address = "New Street",
City = "Lon Angeles", State = "CA", Country = "US", Active = true });
users.Add(new UserInfo() { UserID = "Mike", Address = "Another",
City = "Chicago", State = "IL", Country = "US", Active = false });
users[0].Messages.Add(new Message() { Body = "A Message", Subject = "Test1" });
users[0].Messages.Add(new Message() { Body = "Some Message", Subject = "User message" });
users[0].Messages.Add(new Message() { Body = "Linq Message", Subject = "A Test" });
users[0].Messages.Add(new Message() { Body = "Sent Message", Subject = "Linq is great" });
users[1].Messages.Add(new Message() { Body = "SecondLinq Message", Subject = "Second Test" });
}
So now we have a list of users and that has some data in it, lets look at the LINQ sintax. Say we want to get all the users on the list:
var userQuery =(from UserInfo user in repository.Users
select user);
With variations of this command we can create different objects:
var userArray = (from UserInfo user in repository.Users
select user).ToArray();
var userList = (from UserInfo user in repository.Users
select user).ToList();
var userDictionary = (from UserInfo user in repository.Users
select user).ToDictionary(u => u.UserID, uu => uu);
In the last command we used what is called a Lambda expression to create a Dictionary<string, UserInfo>
. We are not focusing on the amazing world of Lambda,
just understand that these expressions get started with a Object.(variable => variable.property)
. There will be more examples bellow.
Some other available options are:
var userTop5 = (from UserInfo user in repository.Users
select user).Take(5);
var u = (from UserInfo user in repository.Users
select user).Count();
(from UserInfo user in repository.Users
select user).First();
(from UserInfo user in repository.Users
select user).FirstOrDefault();
So far we've looked at a couple of the functions available to us, now we'll do a query that will only get the users that are active and we'll order it by the city. To do this
we have multiple options that will give us the same result:
ViewBag.Model = (from UserInfo user in repository.Users
where user.Active == true
orderby user.City ascending
select user).ToList();
ViewBag.Model = (from UserInfo user in repository.Users
where user.Active == true
select user).OrderBy(o => o.City).ToList();
ViewBag.Model = repository.Users.Where(u => u.Active == true).OrderBy(o => o.City).ToList();
Here's another way of getting all the users:
ViewBag.Model = repository.Users.Select(u => u)
To get all the messages for a specific user:
ViewBag.Model = repository.Users.Where(u => u.UserID == id).SingleOrDefault().Messages;
Now, let’s say that for each message in a user i want to execute a function. Traditionally I would get
the user object and then I would loop through the messages and call the function. LINQ makes this very easy:
private void TestMessage(Message msg)
{
}
public ActionResult UserMessages(string id)
{
Repository repository = new Repository();
ViewBag.Message = "User Messages";
List<Message> messages = repository.Users.Where(u => u.UserID == id).SingleOrDefault().Messages;
messages.ForEach(TestMessage);
ViewBag.Model = messages;
return View();
}
Conclusion
As you can see LINQ makes objects very accessible and easy to use, simplifies code and if you are using the Entity framework or LINQ to SQL, makes adding
records to database tables a simple task. There are a lot more commands for doing joins and more complicated queries but this will give you a starting point.
History