0

I am trying to learn LINQ and I am having a problem with a null ref exception error that I can't understand.

Overview of my project/intent: I have 2 tables in the DB. One is Customers and one is Orders. The Customers table has the ID, Name columns. The Orders table has orderID, Description and CustomerID column.

Customers
ID       Name
1        eeee
2        dddd
3        ffff

Orders
ID       Description   CustomerID
1        sdffds        2
2        dsfasdf       2
3        fjdsa         1
4        dfsa          3

What I am trying to do is to select and display only the customers that have more then 1 orders (in this case, only customer with ID 2).

I have a ViewModel class

 public class ViewModel
    {
      public List<Customer> Customers { get; set; } //list of customer objects 
      public List<Order> Orders { get; set; } //list of customer objects 
    }

In my homecontroller's index action, I have:

        public ActionResult Index()
        {

         Context db = new Context(); //create new Context Object named db which contains lists of objects pulled from database server

         ViewModel model = new ViewModel(); //create new ViewModel Object named model which contains lists of objects

         model.Customers = db.Customers.ToList(); //pull Customers data table from db 

         var groups = db.Orders.GroupBy(custgroup => custgroup.CustomerId).Where(group => group.Count()>1); //pull Orders data table from db and group by CustomerID, and choose only groups with more than 1 records.

            foreach (var group in groups)
            {
                foreach (Order order in group)
                //foreach (var order in group)
                {
                    model.Orders.Add(order); //***The null exception occurs here where 'Orders' is null. Check for null before calling method***
                }
            }


            return View(model);
           }

In effect, what I am trying to do is to group orders by customers and select the groups of orders of my choosing. Then put back the individual records from the groups into the original object format. From the debug, I think I have achieved the filtering process. The problem occurs when I try to put the records back into the 'model.Orders' list.

The null exception occurs inside the inner foreach where 'Orders' list is null. The error indication is that the .Orders list is null and/or has not been declared. But I am thinking that the list was declared in the statement ViewModel model = new ViewModel(); at the top.

How do I fix this null exception error? TIA.

1 Answer 1

4

You forgot to initialize model.Orders.

Put

model.Orders = new List<Order>();

after you create the model and it should work.

Sign up to request clarification or add additional context in comments.

5 Comments

You could also add a private datamember for the Customer property and check if it's null during the get method... But I think just remembering to initialize it is a more simple method.
Thanks Taugenichts, it works, but do you mind explaining why it works? I thought that by declaring - ViewModel model = new ViewModel(); - it would take care of the initialization of the List<Order>. I don't understand why I need to initialize "model.Orders" when I did not need to initialize "model.Customers", but model.Customers could accept values.
Because you set the Customers to an object that was already initialized. The db.Customers is automatically initialized when you access it, but properties are not automatically initialized by default. If you want properties to be initialized when you create an instance of a class, you would have to initialize them in the constructor for the class. Since you are just using the default constructor, none of the properties get set, unless you set them yourself. Only non-object properties would be initialized to default values (int would be set to 0, boolean to false, etc.) Does that make sense?
Thanks Taugenichts, I got the answer for my question. I don't know if that is the same as your answer. The question was WHY I have to declare model.Orders = new List<Order>(); before I can Add() to model.Orders, whereas I did not have to do the same thing for model.Customers. The answer is that in the line model.Customers = db.Customers.ToList(); The ToList() method performed the list instantiation behind the scene.
db.Customers was an initialized entity, and model.Customers was null when you assigned it. The null value got overridden and was replaced with db.Customers.ToList(). To prove this, instead doing model.Customers.AddRange(db.Customers.ToList()); would crash on a null error exception; you can assign values to null values, but calling a method on a null value will crash it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.