Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / ASP.NET

Using basic LINQ commands to query objects in memory

2.22/5 (2 votes)
1 Jun 2012CPOL2 min read 31.9K   172  
Use basic LINQ commands to manipulate and query .net objects.

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.

C#
// Example of ArrayList
ArrayList array = new ArrayList();
array.Add(new UserInfo());
UserInfo userObject = array[0] as UserInfo; //Needs a Cast

But a generic list keeps the object type and we just need to get it from the collection.

C#
// Example of List<>
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:

C#
// User Object
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>();
    }
}

//Message Object
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:

C#
//
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:

C#
var userQuery =(from UserInfo user in repository.Users
                select user);

With variations of this command we can create different objects:

C#
//Create an array
var userArray = (from UserInfo user in repository.Users
             select user).ToArray();
//Create a list
var userList = (from UserInfo user in repository.Users
            select user).ToList();
//Create a dictionary
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:

C#
//Get the first 5 items.
var userTop5 = (from UserInfo user in repository.Users
                select user).Take(5);

//Get a Count of all the items
var u = (from UserInfo user in repository.Users
         select user).Count();

//Get the first item
(from UserInfo user in repository.Users
 select user).First();

//Get the First item or null, if it finds more than one item it'll throw an exception.
(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:

C#
//Select active users with orderby
    //Option 1
ViewBag.Model = (from UserInfo user in repository.Users
                 where user.Active == true
                 orderby user.City ascending
                 select user).ToList();
//Option 2
ViewBag.Model = (from UserInfo user in repository.Users
                 where user.Active == true
                 select user).OrderBy(o => o.City).ToList();

//Option 3
ViewBag.Model = repository.Users.Where(u => u.Active == true).OrderBy(o => o.City).ToList();

Here's another way of getting all the users:

C#
//Select all users
ViewBag.Model = repository.Users.Select(u => u)

To get all the messages for a specific user:

C#
//Select 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:

C#
//Test the user messages
private void TestMessage(Message msg)
{
    //Do Something
}

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;

    //For each object, call the function TestMessage
    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 

  • 5/31/2012: First draft.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)