【问题标题】:How to combine 2different IQueryable/List/Collection with same base class? LINQ Union and Covariance issues如何将 2 个不同的 IQueryable/List/Collection 与相同的基类结合起来? LINQ 联合和协方差问题
【发布时间】:2017-04-25 21:49:24
【问题描述】:

我正在尝试将(联合或连接)两个列表/集合合并为一个。这两个列表有一个共同的基类。例如我试过这个:

        IQueryable<ContractItem> contractItems = myRepository.RetrieveContractItems();
        IQueryable<ChangeOrderItem> changeOrderItems = myRepository.RetrieveChangeOrderItems();

        IQueryable<ItemBase> folderItems = contractItems.Concat<ItemBase>(changeOrderItems);

但是我得到了 LINQ 错误 DbUnionAllExpression 需要具有兼容集合 ResultTypes 的参数。

有人知道如何正确执行此操作吗?我唯一可以谷歌的是另一个 StackOverflow 问题: LINQ Union objects with same Base Class

谢谢。

【问题讨论】:

    标签: linq union covariance


    【解决方案1】:

    使用Cast 运算符:

    IQueryable<ItemBase> folderItems = contractItems
            .Cast<ItemBase>()
            .Concat(changeOrderItems.Cast<ItemBase>());
    

    另一个问题的答案适用于 LINQ to Objects,但不一定适用于 LINQ to Entities 或 LINQ to SQL。

    或者,您可以通过调用 AsEnumerable 转换为 LINQ to Objects:

    IQueryable<ItemBase> folderItems = contractItems
            .AsEnumerable()
            .Concat<ItemBase>(changeOrderItems);
    

    但是,请注意 LINQ to Objects; Concat 可以在没有任何开销的情况下工作(遍历数据库中的两个集合),但 Union 会完全从数据库中提取其中一个集合,然后遍历另一个集合。

    【讨论】:

    • 感谢您的快速响应。我尝试了强制转换运算符,但收到此错误:无法强制转换 ...LINQ to Entities 仅支持强制转换实体数据模型原始类型”。对此有什么想法吗?谢谢。
    • 您可以尝试将Cast 替换为OfTypeItemBase 是实际的 Entity 基类型吗?
    • 我用 LINQ-to-Objects 方法更新了答案,如果我们不能通过 LINQ-to-Entities 让它工作,那肯定会奏效。
    • 我也尝试了 OfType,我得到了这个错误:无法转换... LINQ to Entities 只支持转换实体数据模型原始类型”。但是,我认为你有一点——我的基类不是一个实际的实体,只是一个保存公共属性的公共基类。由于我正在使用 IQueryable,因此 LINQ/Database 无法转换查询......所以我可能必须找到一种方法来显式地“强制转换” "(即创建一个新的 ItemBase 集合),然后返回集合 'AsQueryable'。任何进一步的建议将不胜感激......
    • 太棒了!谢谢!现在是我深入研究 .Net 4.0 对协变和反变的支持的时候了。正如您输入答案一样,我看到 IEnumerable 支持协方差,但 IList 等其他东西不支持......所以再次感谢捆绑! --- 顺便说一句,对您的解决方案的小修复 -- 如果返回类型是 IEnumerable,但如果您希望它作为 IQueryable,则将“.AsQueryable”添加到它。
    猜你喜欢
    • 2022-01-17
    • 2013-06-10
    • 1970-01-01
    • 2011-03-15
    • 1970-01-01
    • 1970-01-01
    • 2019-05-25
    • 1970-01-01
    • 2013-05-11
    相关资源
    最近更新 更多