簡體   English   中英

使用LINQ錯誤比較兩個列表

[英]Wrong Comparison of two list using LINQ

我有兩個類myListClass List

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項目在liJoin

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

現在我想只選擇那些列在liAll但不在liJoin中的liJoin

所以寫了下面的代碼:

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

liFinal沒有給我准確的結果它給了所有liAll項目
所以我的問題是

  1. 上面的代碼有什么問題?
  2. 更好的方法來做到這一點

    更新的代碼

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

首先,您可以使用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的這個答案

您需要為類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,
}

您是否嘗試過使用Enumerable.Except();

liFinal = liAll.Except(liJoin);

在這里了解更多

采用:

var list = liAll.Except(liJoin);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM