C# 使用LINQ查找列表中的项,但获取;值不能为null。参数名称:source";
当使用LINQ从列表中获取数据时,我遇到了这个错误。如何解决这个问题 值不能为null。参数名称:源 我在执行我的LINQ后得到的错误我得到了那种类型的结果(最初只有一行): System.Linq.Enumerable.Where SelectListIteratorC# 使用LINQ查找列表中的项,但获取;值不能为null。参数名称:source";,c#,linq,C#,Linq,当使用LINQ从列表中获取数据时,我遇到了这个错误。如何解决这个问题 值不能为null。参数名称:源 我在执行我的LINQ后得到的错误我得到了那种类型的结果(最初只有一行): System.Linq.Enumerable.Where SelectListIterator 您收到的错误来自与此处显示的方法不同的另一种方法。它是一个采用名为“source”的参数的方法。在Visual Studio选项对话框中,禁用“仅我的代码”,禁用“跳过属性和运算符”并启用“启用.NET Framework源代
您收到的错误来自与此处显示的方法不同的另一种方法。它是一个采用名为“source”的参数的方法。在Visual Studio选项对话框中,禁用“仅我的代码”,禁用“跳过属性和运算符”并启用“启用.NET Framework源代码步进”。确保可以找到.NET符号。如果.NET方法不是您自己的,则调试器将在该方法内部中断。然后检查stacktrace,找出传递的值是null,但不应该是null 您应该查找一个变为
null
的值,并防止它。查看代码时,可能是itemsal.Add
行中断
编辑
由于您似乎在调试方面遇到了问题,特别是LINQ,让我们尝试一步一步地帮助您解决问题(如果您仍然想以经典的方式尝试,请注意上面扩展的第一节,我第一次没有完成):
- 通过拆分代码来缩小可能的错误场景李>
- 将可能以
结尾的位置替换为故意不为null
的位置李>null
- 如果全部失败,请将LINQ语句重写为循环,并一步一步地进行
// 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)
}
}
比如说:
select new
{
SaleID = 123,
LineItem = GetLineItem(new LineItem(/*ctor params for empty lineitem here*/))
};
这会产生垃圾输出,但会将问题进一步缩小到潜在的冒犯范围。对LINQ语句中的其他地方执行与上面相同的操作,这些地方的结果可能是null
(几乎所有内容)
步骤3
这一步你得自己做。但是如果LINQ失败并给您带来这样的麻烦和难以理解或难以调试的代码,那么考虑下一个问题会发生什么?如果它在实时环境中失败了,你必须在时间压力下解决它怎么办=
寓意:学习新技术总是好的,但有时更好的办法是回到清晰易懂的东西上来。没有什么不利于LINQ的,我喜欢它,但在这种特殊情况下,让它休息一下,用一个简单的循环来修复它,并在半年左右的时间里重新访问它
结论
事实上,没有什么结论。我说得再进一步一点,然后我通常会给出一个很长的扩展答案。我只是希望它能帮助您更好地解决这个问题,并让您了解一些工具,了解如何缩小难以调试的情况,即使没有高级调试技术(我们没有讨论过).如果您的数据库模型不正确,并且基础数据包含模型试图映射到非空对象的空值,则可能会出现此错误 例如,一些自动生成的模型可以尝试将nvarchar(1)列映射到char而不是string,因此,如果此列包含null,则在尝试访问数据时将抛出错误
注意,如果您希望LinqPad生成这样的模型,那么它有一个兼容性选项,但默认情况下可能不会这样做,这可能解释了它不会给您带来错误。此异常可能指向名为source的LINQ参数:
System.Linq.Enumerable.Select[TSource,TResult](IEnumerable`1 source, Func`2 selector)
由于
LINQ
查询(var nCounts=from sale in sal
)中的source
参数是“sal
”,我想名为“sal”的列表可能是空的。好的-我的案例与这个问题没有严格的关系,但我在谷歌搜索相同的异常时出现在这个页面上;当我得到这个异常时,我用LINQ查询了一个SQL数据库
private Table<SubscriptionModel> m_subscriptionsSql;
var query = from SubscriptionModel subscription in m_subscriptionsSql ...
私有表m_subscriptionsSql;
var query=来自m_SubscriptionSQL中的SubscriptionModel订阅。。。
结果我忘了初始化我在LINQ查询中使用的表实例变量
m_subscriptionsSql = GetTable<SubscriptionModel>();
m_subscriptionsSql=GetTable();
以下是更多生成参数null异常的代码示例:
List<Myobj> myList = null;
//from this point on, any linq statement you perform on myList will throw an argument null exception
myList.ToList();
myList.GroupBy(m => m.Id);
myList.Count();
myList.Where(m => m.Id == 0);
myList.Select(m => m.Id == 0);
//etc...
List myList=null;
//从这一点开始,您在myList上执行的任何linq语句都将抛出一个参数null异常
myList.ToList();
myList.GroupBy(m=>m.Id);
myList.Count();
其中(m=>m.Id==0);
myList.Select(m=>m.Id==0);
//等等。。。
此错误可能发生在多个地方,最常见的是在空集合上运行进一步的LINQ查询。LINQ as查询语法看起来比实际更安全。考虑以下样本:
var filteredCollection = from item in getMyCollection()
orderby item.ReportDate
select item;
此代码不是空安全的,这意味着如果getMyCollection()
返回空值,您将得到值不能为空。参数名称:源
错误。非常讨厌!但这很有意义,因为LINQ查询语法只是这个等价代码的语法糖:
var filteredCollection = getMyCollection().OrderBy(x => x.ReportDate);
如果起始方法返回null,显然会爆炸
为了防止这种情况,可以在LINQ查询中使用空合并运算符,如下所示:
var filteredCollection = from item in getMyCollection() ??
Enumerable.Empty<CollectionItemClass>()
orderby item.ReportDate
select item;
var filteredCollection=来自getMyCollection()中的项??
Enumerable.Empty()
orderby item.ReportDate
选择项目;
但是,您必须记住在任何相关查询中都要这样做。最好的方法(如果您控制生成集合的代码)是将永远不返回空集合作为一种编码实践。在某些情况下,从“getCustomerById(string id)
”这样的方法返回空对象是可以的,这取决于您的团队编码风格,但是如果您有一个返回业务对象集合的方法,比如“getAllcustomers()
”,那么它永远不应该返回空数组/可枚举的/etc.
var filteredCollection = getMyCollection().OrderBy(x => x.ReportDate);
var filteredCollection = from item in getMyCollection() ??
Enumerable.Empty<CollectionItemClass>()
orderby item.ReportDate
select item;