Linq对象集合的结果

时间:2014-02-07 19:45:40

标签: c# .net linq

我遇到了一个我可以解决的问题,但我觉得Linq中应该有一个我没有看到的解决方案。

所以我有两个类,一个详细记录类和这些类的集合:

public class ItemDetail
{
    public string Name {get;set;}
    public int? Id {get;set;}
}

public class ItemDetailCollection : List<ItemDetail>
{
}

现在,我可以使用我的存储库层填充这些对象而没有问题,并查询数据以获取我想要的记录子集。

var items = Repository.GetItemCollection();
var reportItemCollection = items.Where(x=>x.Id.HasValue);

这一切都很好,花花公子。但是,reportItemCollectionIEnumberable<ItemDetail>,我真正想要的是新的ItemDetailCollection

当然,我可以创建一个新的集合并添加查询范围,但我觉得有一种方法可以自动将结果集填充为特定的集合类型。我尝试添加以下内容,只收到NULL的结果:

var reportItemCollection = items.Where(x=>x.Id.HasValue) as ItemDetailCollection;

尝试.Cast<ItemDetailCollection>()也不起作用。最后,我试过了

var reportItemCollection = items.Where(x=>x.Id.HasValue).Select(result => new ItemDetailCollection(){ result });

但这只给了我一个IEnumerable<ItemDetailCollection>

有什么想法吗?

2 个答案:

答案 0 :(得分:9)

唯一的方法是使用List<T>的构造函数实际构建集合:

public class ItemDetailCollection : List<ItemDetail>
{
    public ItemDetailCollection(IEnumerable<ItemDetail> items)
        : base(items) { }
}

var reportItemCollection = new ItemDetailCollection(
    items.Where(x=>x.Id.HasValue)
);

由于协方差/逆变规则,您无法将IEnumerable<T>强制转换为类似ItemDetailCollection的子类(请参阅此处,例如:http://blogs.msdn.com/b/csharpfaq/archive/2010/02/16/covariance-and-contravariance-faq.aspx)。

答案 1 :(得分:4)

我会像LINQ为List<T>解决它一样解决这个问题:创建一个ToItemDetailCollection扩展方法

static ItemDataCollection ToItemDataCollection(this IEnumerable<ItemDetail> e) {
  return new ItemDataCollection(e);
}

然后你可以将它附加到任何查询

var reportItemCollection = items
  .Where(x=>x.Id.HasValue)
  .ToItemDataCollection();

另外,我会问你为什么要从List<T>派生出来。它没有提供virtual方法来覆盖,因此不可能进行自定义。在List<ItemDetail>到处使用它只会引起很多像这样的痛点。