使用LINQ错误比较两个列表

时间:2014-01-13 11:49:03

标签: c# .net linq list

我有两个List课程myListClass其中

public class myListclass
{
    public Nullable<decimal> ClassId { get; set;}
    public Nullable<decimal> SectionId { get; set; }
    public Nullable<decimal> MediumId { get; set; }
    public Nullable<decimal> StreamId { get; set; }
    public Nullable<decimal> ShiftId { get; set; }
}  

其中list1是

List<myListclass> liAll = new List<myListclass>();   

liAll中的项目

ClassId Section MediumId Stream  Shift
73     220       207    145       128
73     221       207    145       128
73     222       207    145       128
74     220       207    145       128
74     221       207    145       128
75     220       207    145       128
75     221       207    145       128
76     220       207    145       128
76     221       207    145       128
77     220       207    145       128
77     221       207    145       128
78     220       207    145       128  

而list2是

List<myListclass> liJoin = new List<myListclass>(); 

liJoin中的项目

ClassId Section MediumId Stream  Shift
73     220       207    145       128
73     221       207    145       128  

现在我想只将这些项目选择到liAll但不在liJoin

中的列表中

所以写了下面的代码:

List<myListclass> liFinal = new List<myListclass>(); 
liFinal = liAll.Where(w => !liJoin.Contains(w)).ToList();  

但是liFinal没有给我准确的结果,它会提供liAll的所有项目 所以我的问题是

  1. 上面代码出了什么问题?
  2. 更好的方法

    更新了代码

    liFinal = liAll.Where(w =&gt;!liJoin.Select(s =&gt; s.ClassId).Contains(w.ClassId)&amp;&amp;
                !liJoin.Select(s =&gt; s.MediumId).Contains(w.MediumId)&amp;&amp;&amp;             !liJoin.Select(s =&gt; s.SectionId).Contains(w.SectionId)&amp;&amp;
                !liJoin.Select(s =&gt; s.ShiftId).Contains(w.ShiftId)&amp;&amp;
                !liJoin.Select(s =&gt; s.StreamId).Contains(w.StreamId))。ToList();

4 个答案:

答案 0 :(得分:3)

首先,您可以使用LINQ Except方法来获取缺少的元素:

List<myListclass> liFinal = liAll.Except(liJoin).ToList();  

为此(以及其他基于平等的操作),您需要在班级上实施IEquatable<T>

public class myListclass : IEquatable<myListclass>
{
    public Nullable<decimal> ClassId { get; set; }
    public Nullable<decimal> SectionId { get; set; }
    public Nullable<decimal> MediumId { get; set; }
    public Nullable<decimal> StreamId { get; set; }
    public Nullable<decimal> ShiftId { get; set; }

    public bool Equals(myListclass other)
    {
        return
            other != null &&
            this.ClassId == other.ClassId &&
            this.SectionId == other.SectionId &&
            this.MediumId == other.MediumId &&
            this.StreamId == other.StreamId &&
            this.ShiftId == other.ShiftId;
    }

    public override bool Equals(object obj)
    {
        return this.Equals(obj as myListclass);
    }

    public override int GetHashCode()
    {
        // https://stackoverflow.com/a/263416/1149773
        unchecked
        {
            int hash = 17;
            hash = hash * 23 + ClassId.GetHashCode();
            hash = hash * 23 + SectionId.GetHashCode();
            hash = hash * 23 + MediumId.GetHashCode();
            hash = hash * 23 + StreamId.GetHashCode();
            hash = hash * 23 + ShiftId.GetHashCode();
            return hash;
        }
    }
}  

GetHashCode()方法的实施改编自Jon Skeet的this answer

答案 1 :(得分:0)

您需要为您的类MyListClass重写Equals方法。

请点击此链接。这将告诉您如何为您的班级实现此目的。

http://msdn.microsoft.com/en-us/library/dd183755.aspx

这是我用来覆盖相同方法的剪辑。

public override bool Equals(object obj)
{
    return Equals(obj as $className$);
}
internal bool Equals($className$ other)
{
    // If parameter is null, return false. 
    if (ReferenceEquals(other, null))
        return false;

    // Optimization for a common success case. 
    if (ReferenceEquals(this, other))
        return true;

    return // TODO: compare this.Memeber1 == other.Member2,
    // if equal return true,
}

答案 2 :(得分:0)

您是否尝试过使用Enumerable.Except();

liFinal = liAll.Except(liJoin);

Here了解更多

答案 3 :(得分:0)

使用:

var list = liAll.Except(liJoin);