tags:

views:

164

answers:

2

Hi i am using linq to get the data from list but as i get the in linq i use foreach loop to add it in generic list but i got error " Value cannot be null. Parameter name: source"

i am using c# With .net

my code

 var nCounts = from sale in sal
                              select new
                              {
                                  SaleID = sale.OrderID,
                                  LineItem = from sli in sale.LineItems
                                             group sli by sli.Item into ItemGroup
                                             select new
                                             {
                                                 Item = ItemGroup.Key,
                                                 Weeks = ItemGroup.Select(s => s.Week)
                                             }

                              };

                foreach (var item in nCounts)
                {
                    foreach (var itmss in item.LineItem)
                    {
                        // MessageBox.Show(itmss.Item.Name);
                        itemsal.Add(new Roundsman.BAL.WeeklyStockList(itmss.Item.Name.ToString(), itmss.Item.Code.ToString(), itmss.Item.Description.ToString(),
                            Convert.ToInt32(itmss.Item.Quantity), 2, 2, 2, 2, 2, 2, 2, 2, 2));
                    }
                    //itemsal.Add(new Roundsman.BAL.WeeklyStockList(item.LineItem.Select(i => new { i.Item.Name }).ToString(), item.LineItem.Select(i => new { i.Item.Code }).ToString(), "", 1, 2, 2, 2, 2, 2, 2, 2, 2, 2));
                }

Edit

Error which i got after execution my LINQ I got that type of result (one line, orginally):

System.Linq.Enumerable.WhereSelectListIterator<Roundsman.BAL.Sale, 
    <>f__AnonymousType1<int,System.Collections.Generic.IEnumerable 
    <<>f__AnonymousType0<Roundsman.BAL.Items.Item,System.Collections.Generic.IEnumerable 
    <Roundsman.BAL.WeeklyRecord>>>>>
+1  A: 

The error you receive is from another method than the one you show here. It's a method that takes a parameter with the name "source". In your Visual Studio Options dialog, disable "Just my code", disable "Step over properties and operators" and enable "Enable .NET Framework source stepping". Make sure the .NET symbols can be found. Then the debugger will break inside the .NET method if it isn't your own. then check the stacktrace to find which value is passed that's null, but shouldn't.

What you should look for is a value that becomes null and prevent that. From looking at your code, it may be the itemsal.Add line that breaks.

Edit

Since you seem to have trouble with debugging in general and LINQ especially, let's try to help you out step by step (also note the expanded first section above if you still want to try it the classic way, I wasn't complete the first time around):

  • Narrow down the possible error scenarios by splitting your code;
  • Replace locations that can end up null with something deliberately not null;
  • If all fails, rewrite your LINQ statement as loop and go through it step by step.

Step 1

First make the code a bit more readable by splitting it in manageable pieces:

// in your using-section, add this:
using Roundsman.BAL;

// keep this in your normal location
var nCounts = from sale in sal
              select new
              {
                  SaleID = sale.OrderID,
                  LineItem = GetLineItem(sale.LineItems)
              };

foreach (var item in nCounts)
{
    foreach (var itmss in item.LineItem)
    {
        itemsal.Add(CreateWeeklyStockList(itmss));
    }
}


// add this as method somewhere
WeeklyStockList CreateWeeklyStockList(LineItem lineItem)
{
    string name = itmss.Item.Name.ToString();  // isn't Name already a string?
    string code = itmss.Item.Code.ToString();  // isn't Code already a string?
    string description = itmss.Item.Description.ToString();  // isn't Description already a string?
    int quantity = Convert.ToInt32(itmss.Item.Quantity); // wouldn't (int) or "as int" be enough?

    return new WeeklyStockList(
                 name, 
                 code, 
                 description,
                 quantity, 
                 2, 2, 2, 2, 2, 2, 2, 2, 2
              );
}

// also add this as a method
LineItem GetLineItem(IEnumerable<LineItem> lineItems)
{
    // add a null-check
    if(lineItems == null)
        throw new NullReferenceException("Cannot be null!!!");

    // your original code
    from sli in lineItems
    group sli by sli.Item into ItemGroup
    select new
    {
        Item = ItemGroup.Key,
        Weeks = ItemGroup.Select(s => s.Week)
    }
}

The code above is from the top of my head, of course, because I cannot know what type of classes you have and thus cannot test the code before posting. Nevertheless, if you edit it until it is correct (if it isn't so out of the box), then you already stand a large chance the actual error becomes a lot clearer. If not, you should at the very least see a different stacktrace this time (which we still eagerly await!).

Step 2

The next step is to meticulously replace each part that can result in a null reference exception. By that I mean that you replace this:

select new
{
    SaleID = sale.OrderID,
    LineItem = GetLineItem(sale.LineItems)
};

with something like this:

select new
{
    SaleID = 123,
    LineItem = GetLineItem(new LineItem(/*ctor params for empty lineitem here*/))
};

This will create rubbish output, but will narrow the problem down even further to your potential offending line. Do the same as above for other places in the LINQ statements that can end up null (just about everything).

Step 3

This step you'll have to do yourself. But if LINQ fails and gives you such headaches and such unreadable or hard-to-debug code, consider what would happen with the next problem you encounter? And what if it fails on a live environment and you have to solve it under time pressure=

The moral: it's always good to learn new techniques, but sometimes it's even better to grab back to something that's clear and understandable. Nothing against LINQ, I love it, but in this particular case, let it rest, fix it with a simple loop and revisit it in half a year or so.

Conclusion

Actually, nothing to conclude. I went a bit further then I'd normally go with the long-extended answer. I just hope it helps you tackling the problem better and gives you some tools understand how you can narrow down hard-to-debug situations, even without advanced debugging techniques (which we haven't discussed).

Abel
thanks for you rply the error raises at "foreach (var item in nCounts)"
Emaad Ali
@Emaad Ali: That means that the error is actually inside the LINQ code, for instance if `Week` is null in `s.Week`. Uncheck "Just my code", enable the exception assistant and break on the error, check the values by hovering over them with your mouse, doubleclick the stack calls until you find the offending code.
Abel
i disable just my code and make that code in try catch but the error raises same.
Emaad Ali
If you have trouble getting in or understanding the stacks of LINQ, have a look at LINQPad: http://www.linqpad.net/ it will help you debug your LINQ statements. Fact is, and remains, that one of your value is null that shouldn't be. Replace the possibly offending statements `xyz` with `xyz ?? defaultXyz` and you have another go at your solution (just replace every nullable value one by one, run, and once it works, you know which was the wrong one, ugly, but it helps).
Abel
i use that thing also but no error produce from linqpad.is there any other way to check linq which item is null?
Emaad Ali
after executing my linq i got that type of resultSystem.Linq.Enumerable.WhereSelectListIterator<Roundsman.BAL.Sale,<>f__AnonymousType1<int,System.Collections.Generic.IEnumerable<<>f__AnonymousType0<Roundsman.BAL.Items.Item,System.Collections.Generic.IEnumerable<Roundsman.BAL.WeeklyRecord>>>>>
Emaad Ali
@Emaad Ali: please don't double-post your comments (you can delete them if you wish). This is excellent information, along with the full stacktrace which we asked for a few times. But this information is good for everybody, so add it to your question (click Edit) with the proper layout.
Abel
@Abel it still not working
Emaad Ali
@Emaad Ali: you are not really helping me helping you. After I went to so much trouble showing you how to solve it, it helps me little that you just say "it doesn't work". What have you tried, how have you tried it, what is your resulting code and please, please, please, answer all the questions we've had so far and update your original q. with an edit showing the stacktrace, the new code (with the for-each loops instead of LINQ) etc (please also leave the original code in your post). If you want help, you have to help us by starting giving information and follow our suggestions.
Abel
i tried alot to find the problem but cant figure it out but thanks alot to you for helping me too much...thanks
Emaad Ali
@Emaad Ali: Of course you tried a lot, there isn't a minute I doubted that, but the thing is: what did you try and did you understand all the steps explained to you and to what extend? What's the resulting code looking like? What are the new errors? You are our eyes and hands, without a very detailed description of what you did, we cannot help you further, simply because we can't *see* or *guess* what you did.
Abel
A: 

I think you can get this error if your database model is not correct and the underlying data contains a null which the model is attempting to map to a non-null object.

For example, some auto-generated models can attempt to map nvarchar(1) columns to char rather than string and hence if this column contains nulls it will throw an error when you attempt to access the data.

Note, LinqPad has a compatibility option if you want it to generate a model like that, but probably doesn't do this by default, which might explain it doesn't give you the error.

sgmoore
after executing my linq i got that type of result System.Linq.Enumerable.WhereSelectListIterator<Roundsman.BAL.Sale, <>f__AnonymousType1<int,System.Collections.Generic.IEnumerable <<>f__AnonymousType0<Roundsman.BAL.Items.Item,System.Collections.Generic.IEnumerable <Roundsman.BAL.WeeklyRecord>>>>>
Emaad Ali
The only extra info that I can glean from this is that sale.OrderID is mapped to an int and hence could give an error if the column happens to be null.Can you narrow the code down any more. Can you remove the inner loop and still replicate the problem? (In fact, can you remove references to LineItem altogether and see if it works?)
sgmoore