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

标签 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
                                        }
                            };

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

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/

相关文章:

c# - 为什么我的转换/转换失败?

c# - 在负载均衡器和 SSL 后面配置 WCF

c# - 使用LINQ to XML查询子节点的内部xml

c# - 缓存 Linq 查询问题

c# - 在字符串列表中查找公共(public)字符串

c# - 在新线程上打开选项卡项?

c# - 预测中的蒙特卡罗模拟?

c# - 如何使用 linq 仅对一列进行分组

c# - Linq Union,避免空数据和重复数据

linq - 查询数据库中距离邮政编码 n 英里内的记录的最佳方法是什么?