我在使用以下 LINQ 查询时遇到问题。当嵌套查询 (item.Items) 没有对象时,我收到异常“值不能为空。参数名称:源。”。
如何让内部查询向查询中的项目返回一个空列表?
var items = from item in _repository.GetStreamItems()
select new
{
Title = item.Title,
Description = item.Description,
MetaData = item.MetaData,
ItemType = item.ItemType,
Items = from subItem in item.Items
select new
{
Title = subItem.Title,
Description = subItem.Description,
MetaData = subItem.MetaData,
ItemType = subItem.ItemType
}
};
这是使用方法调用而不是查询语法编写的相同查询。同样的问题:
var items = _repository.GetStreamItems()
.Select(x => new { Title = x.Title, Description = x.Description, MetaData = x.MetaData, ItemType = x.ItemType,
Items = x.Items.Select(x2 => new { Title = x2.Title, Description = x2.Description, MetaData = x2.MetaData, ItemType = x2.ItemType,
Items = x2.Items.Select(x3 => new { Title = x3.Title, Description = x3.Description, MetaData = x3.MetaData, ItemType = x3.ItemType }) }) });
关于如何测试或避免 null item.Items 值的任何想法?我有一种感觉,我缺少的是一些简单的东西。
最佳答案
假设它是 LINQ to Objects 并且单个项目类名称是 Item
,使用这个:
var items = from item in _repository.GetStreamItems()
select new
{
Title = item.Title,
Description = item.Description,
MetaData = item.MetaData,
ItemType = item.ItemType,
Items = from subItem in (item.Items ?? Enumerable.Empty<Item>())
select new
{
Title = subItem.Title,
Description = subItem.Description,
MetaData = subItem.MetaData,
ItemType = subItem.ItemType
}
};
??
被称为 null-coalescing operator如果左边的值为null
,则返回右边的值。
在您的具体示例中,我们提供了一个空序列而不是 null
,因此代码不会崩溃。
问题是您不能将查询应用于 null
对象,而且您的 item.Items
似乎可以是 null
案件。更好的解决方案是确保 Items
属性在为空时返回零序列,而不是 null
。
如果您无法控制 StreamItem
类,但必须在许多地方执行类似的查询,那么创建一个返回“无效化”项目的“安全”扩展方法可能会有所返回:
public static IEnumerable<Item> SafeGetSubItems(this StreamItem parent)
{
return parent.Items ?? Enumerable.Empty<Item>();
}
这将允许你总是写:
Items = from subItem in item.SafeGetSubItems()
select new
{
// ...
}
关于c# - 在 linq 查询中有条件地填充匿名类型成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6997337/