在linq查询中有条件地填充匿名类型成员

jos*_*shb 4 c# linq

我遇到以下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
                                        }
                            };
Run Code Online (Sandbox Code Playgroud)

这是使用方法调用而不是查询语法编写的相同查询.同样的问题:

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 }) }) });
Run Code Online (Sandbox Code Playgroud)

任何想法如何测试或避免null item.Items值?我觉得这很简单,我很想念.

Dan*_*mov 6

假设它是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
                                    }
                        };
Run Code Online (Sandbox Code Playgroud)

??被称为null-coalescing运算符,如果左边的值是,则返回右边的值null.
在您的具体示例中,我们提供一个空序列而不是null代码不会崩溃.

问题是你无法对一个null对象应用查询,而且似乎item.Items可以null在你的情况下.更好的解决方案是确保Items属性在空时返回零​​序列,而不是null.

如果您无法控制StreamItem该类但必须在许多地方执行类似的查询,那么创建一个"安全"扩展方法可能会返回"denullified"项目:

public static IEnumerable<Item> SafeGetSubItems(this StreamItem parent)
{
    return parent.Items ?? Enumerable.Empty<Item>();
}
Run Code Online (Sandbox Code Playgroud)

这将允许你总是写:

Items = from subItem in item.SafeGetSubItems()
        select new
        {
            // ...
        }
Run Code Online (Sandbox Code Playgroud)