使用LINQ找到一个列表项,但得到"值不能为空。参数名:源" [英] Using LINQ to find item in a List but get "Value cannot be null. Parameter name: source"

查看:1044
本文介绍了使用LINQ找到一个列表项,但得到"值不能为空。参数名:源"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在使用LINQ to从我遇到这个错误列表获取数据。这怎么能解决吗?


  

值不能为空。参数名:源


  VAR nCounts =从萨尔销售
              新选择
              {
                  SaleID = sale.OrderID,
                  LineItem的从sale.LineItems SLI =
                             组SLI通过sli.Item成的ItemGroup
                             新选择
                             {
                                 项目= ItemGroup.Key,
                                 周= ItemGroup.Select(S => s.Week)
                             }
              };的foreach(在nCounts VAR项)
{
    的foreach(在item.LineItem VAR itmss)
    {
        // MessageBox.Show(itmss.Item.Name);
        itemsal.Add(新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));
    }
}

错误,我执行我的LINQ后,得到了我得到的结果类型(一行,orginally):


  

&System.Linq.Enumerable.WhereSelectListIterator LT; Roundsman.BAL.Sale,
      <> F_的 AnonymousType1< INT,System.Collections.Generic.IEnumerable
      <<>˚F
的_AnonymousType0< Roundsman.BAL.Items.Item,System.Collections.Generic.IEnumerable
      < Roundsman.BAL.WeeklyRecord >>>>>
  



解决方案

您收到的错误是比你在这里展示的另一个方法。它是采用名为源参数的方法。在你的Visual Studio选项对话框,禁用只是我的code,禁用步骤在性能和运营商,并启用启用.NET框架源步进。确保.NET符号可以找到。然后,调试器将打破.NET方法中,如果它是不是你自己的。然后检查堆栈跟踪找到其值传递那是空的,但不应该。

你应该寻找是成为和prevent一个值。从看你的code,这可能是压垮 itemsal.Add 行。

修改

因为你似乎有一般和LINQ调试麻烦尤其是,让我们尝试帮助你一步一步(也注意到上面,如果你还是想尝试一下经典的方式展开的第一部分,我是不完全第一次左右):


  • 通过拆分您code缩小可能的错误情况;

  • 替换,可最终位置的东西故意不;

  • 如果所有的失败,重写你的LINQ语句,循环,并通过它一步一步。

步骤1

首先使code可读性更强一点在管理的部分分裂的:

 在使用截面//,补充一点:
使用Roundsman.BAL;//记住这你的正常的位置
从萨尔销售VAR nCounts =
              新选择
              {
                  SaleID = sale.OrderID,
                  项= GetLineItem(sale.LineItems)
              };的foreach(在nCounts VAR项)
{
    的foreach(在item.LineItem VAR itmss)
    {
        itemsal.Add(CreateWeeklyStockList(itmss));
    }
}
//某处添加为方法
WeeklyStockList CreateWeeklyStockList(LineItem的订单项)
{
    字符串名称= itmss.Item.Name.ToString(); //尚未命名一个字符串?
    。字符串code = itmss.Item code.ToString(); //不是code已经是一个字符串?
    字符串描述= itmss.Item.Description.ToString(); //是不是说明已经是一个字符串?
    INT数量= Convert.ToInt32(itmss.Item.Quantity); //不会(INT)或为诠释就够了吗?    返回新WeeklyStockList(
                 名称,
                 code,
                 描述,
                 数量,
                 2,2,2 2,2 2,2 2,2
              );
}//还添加为方法
LineItem的GetLineItem(IEnumerable的<&LineItem的GT;了LineItem)
{
    //添加一个空检查
    如果(==了LineItem空)
        抛出新的ArgumentNullException(了LineItem,参数不能为空!);    //你原来的code
    在SLI了LineItem
    组SLI通过sli.Item成的ItemGroup
    新选择
    {
        项目= ItemGroup.Key,
        周= ItemGroup.Select(S => s.Week)
    }
}

上面的code是从我的头顶,当然,因为我不知道你有什么类型的课程,因此在发布前无法测试code。不过,如果你编辑它,直到它是正确的(如果不是这样的开箱),那么你已经站在一个大的机会,实际的错误变得更加清晰。如果没有,你应该最起码看到一个不同的堆栈跟踪这个时候(我们仍然热切地等待!)。

步骤2

的下一个步骤是精心更换,可能导致一个空引用异常每个部分。我的意思是,你替换此:

 新选择
{
    SaleID = sale.OrderID,
    项= GetLineItem(sale.LineItems)
};

像这样的东西:

 新选择
{
    SaleID = 123,
    项= GetLineItem(新的LineItem(/ *构造函数PARAMS空LINEITEM这里* /))
};

这将创建一个生活垃圾产生量,反而会进一步缩小问题到你的潜在违规行。做同上在LINQ语句可以结束了(刚才的一切)等地。

步骤3

这一步,你必须做你自己。但是,如果LINQ失败,并为您提供了这样的头痛,如无法阅读或难以调试code,可以考虑将与您遇到的一个问题发生什么呢?而如果它失败在实际环境中,你必须解决它下一次pressure =

寓意:它总是好学习新技术,但有时它抢回来的东西,就是清晰易懂的甚至更好。对LINQ没什么,我喜欢它,但在这种特殊情况下,让它休息,用一个​​简单的循环修复它,并在半年左右重新考虑。

结论

其实,没有得出结论。我去一个远一点,然后我通常与长期扩展的答案去。我只希望它可以帮助你解决这个问题更好,为您提供了一些工具,了解如何才能缩小难以调试的情况下,即使没有高级调试技术(我们还没有讨论)。

When using LINQ to get data from a list I encounter this error. How can this be fixed?

Value cannot be null. Parameter name: source

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));
    }                      
}

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>>>>>

解决方案

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 ArgumentNullException("lineItems", "Argument 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).

这篇关于使用LINQ找到一个列表项,但得到&QUOT;值不能为空。参数名:源&QUOT;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆