【问题标题】:Do list except with two list of different classes instances列出除了两个不同类实例的列表
【发布时间】:2017-11-13 08:55:48
【问题描述】:

我想将两个列表与两个不同类的对象进行比较。这些是类:

namespace AngularWebApplication.Models
{
    public class AggregationLevelConfigurationPresentation
    {
        public byte AggregationLevelConfigurationId { get; set; }
        public int ProductionOrderId { get; set; }
        public string Name { get; set; }
        [ ... ]
    }
}

public class AggregationLevelConfiguration : IEquatable<AggregationLevelConfiguration>
{
    public byte AggregationLevelConfigurationId { get; set; }
    public int ProductionOrderId { get; set; }
    public string Name { get; set; }
    [ ... ]
}

我想获取presentations列表中不在currentLevels中的元素:

列出演示文稿; 列出当前级别;

List<Models.AggregationLevelConfigurationPresentation> newLevels =
    presentations
        .Select(l => new { l.AggregationLevelConfigurationId, l.ProductionOrderId })
        .Except(currentLevels.Select(l => new { l.AggregationLevelConfigurationId, l.ProductionOrderId }))
        .ToList();

但是当我执行Except 时出现以下错误:

Error   CS0029  Cannot implicitly convert type 
'System.Collections.Generic.List<<anonymous type: byte AggregationLevelConfigurationId, int ProductionOrderId>>' to 
'System.Collections.Generic.List<AngularWebApplication.Models.AggregationLevelConfigurationPresentation>'

我认为问题出在new { l.AggregationLevelConfigurationId, l.ProductionOrderId },但我不知道如何使用来自不同类的对象列表来处理Except

我需要使用AggregationLevelConfigurationIdProductionOrderId 作为主键列出presentations 中不在currentLevels 中的对象。

【问题讨论】:

  • 可以尝试改写标题吗?在阅读问题之前我无法理解它。
  • 您正在选择匿名类型,那么为什么您期望ToList 创建一个List&lt;AggregationLevelConfigurationPresentation&gt;
  • @TimSchmelter 我希望有一个List&lt;Models.AggregationLevelConfigurationPresentation&gt;
  • 我建议不要在这种情况下使用Except。相反,你可以做类似presentations.Where(p =&gt; !currentLevels.Any(l =&gt; p.AggregationLevelConfigurationId == l.AggregationLevelConfigurationId))
  • @CodeCaster,在所有版本中,问题都是“我想获取演示列表中不在 currentLevels 中的元素”。编译器错误只是 OP 尝试这样做的副产品。

标签: c#


【解决方案1】:

您的Execept-查询选择匿名类型,因此ToList 不会创建List&lt;AggregationLevelConfigurationPresentation&gt;。您必须创建此类的实例:

List<AggregationLevelConfigurationPresentation> newLevels = presentations
        .Select(l => new { l.AggregationLevelConfigurationId, l.ProductionOrderId })
        .Except(currentLevels.Select(l => new { l.AggregationLevelConfigurationId, l.ProductionOrderId }))
        .Select(x => new AggregationLevelConfigurationPresentation 
        { 
            AggregationLevelConfigurationId = x.AggregationLevelConfigurationId,  
            ProductionOrderId = x.ProductionOrderId
         })
        .ToList();

我需要它们不在的演示列表中的对象 currentLevels 使用 AggregationLevelConfigurationId 和 ProductionOrderId 作为主键。

那么你可以使用Join:

var except = presentations
        .Select(l => new { l.AggregationLevelConfigurationId, l.ProductionOrderId })
        .Except(currentLevels.Select(l => new { l.AggregationLevelConfigurationId, l.ProductionOrderId }));

var newLevels = from x in except
                join p in presentations 
                on x equals new { p.AggregationLevelConfigurationId, p.ProductionOrderId }
                select p;
List<AggregationLevelConfigurationPresentation> newLevelList = newLevels.ToList();

【讨论】:

  • 我怀疑 OP 想要这个。他想要原始 presentations 列表中的项目,而不是新项目(即使只填充了 2 个属性)。
  • 但这会返回一个对象列表,其中只有AggregationLevelConfigurationIdProductionOrderId 中的值,我需要presentations 列表中的对象,它们不在currentLevels 中,使用AggregationLevelConfigurationId ProductionOrderId 作为主键。
【解决方案2】:

在 Evk 评论之后,这就是我解决此问题的方法:

List<Models.AggregationLevelConfigurationPresentation> newLevels =
     presentations.Where(p => !currentLevels.Any(l => p.AggregationLevelConfigurationId == l.AggregationLevelConfigurationId && p.ProductionOrderId == l.ProductionOrderId));

【讨论】:

    猜你喜欢
    • 2020-07-28
    • 1970-01-01
    • 1970-01-01
    • 2013-12-29
    • 2010-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-12
    相关资源
    最近更新 更多