2015-07-12 66 views
-2

我想检测一些数据是否使用Linq进行了更改。C#/ Linq:检测到的两个列表之间的差异键入

我有这个类:

public class MyData 
{ 
    public string Nombre {get; set;} 
    public string Tipo {get; set;} 
    public int Longitud {get; set;} 
} 

我有类型化类,我可以改变数据,另一种是变更前的副本列表。

类型的结构:

List<MyData> data = new List<MyData>(); 

// suppose I load data here in data variable. 

List<MyData> mycopy = data; 

var mydatatochange = data.Where(...).ToList(); 

mydatatochange 

...or... 

MyData info = new MyData(); 
info.Nombre = "aaa"; 
info.Tipo = "something"; 

data.Add(info); 

现在我想看看是否datamycopy之间有某种差异。

我想用Linq来使用它。

+0

显示填充数据列表的某些部分。其重要的 –

回答

2

这是检测添加,删除和更改项目的代码:

List<MyData> lst = new List<MyData>(); 

lst.Add(new MyData() 
     { 
      Longitud = 1, 
      Tipo = "123", 
      Nombre = "n1" 
     }); 


     lst.Add(new MyData() 
     { 
      Longitud = 1, 
      Tipo = "456", 
      Nombre = "n1" 
     }); 

     var cloned = lst.ToList(); 
     Dictionary<MyData, Tuple<string, string, int>> originalValues = new Dictionary<MyData, Tuple<string, string, int>>(); 

     foreach (var item in cloned) 
      originalValues[item] = new Tuple<string, string, int>(item.Nombre, item.Tipo, item.Longitud); 


     cloned.Remove(lst[0]); 
     cloned.Add(new MyData() 
     { 
      Longitud = 2, 
      Nombre = "aaaaaa", 
      Tipo = "gggg" 
     }); 

     var added = (from p in cloned 

        join orig in lst 
         on p equals orig into left 
        from orig in left.DefaultIfEmpty() 
        where orig == null 
        select p).ToList(); 

     var deleted = (from orig in lst 
         join c in cloned 
          on orig equals c into left 
         from c in left.DefaultIfEmpty() 
         where c == null 
         select orig).ToList(); 

     var changed = (from orig in lst 
         join c in cloned 
          on orig equals c 
         where originalValues[orig].Item1 != orig.Nombre || 
          originalValues[orig].Item2 != orig.Tipo || 
          originalValues[orig].Item3 != orig.Longitud 
         select orig 
          ).ToList(); 
1

为了检查一个对象等于另一个你可以使用的Object.Equals(otherObject),但...

在你的榜样,你做的事:List<MyData> mycopy = data;该不会是复制,但它会创建的指针一样如果您更改数据对象,该对象也会发生变化。所以为了使其工作:

1)编辑MyData的类这样的代码:

public class MyData 
{ 
    public MyData(string nombre, string tipo, int longitud) 
    { 
     Nombre = nombre; 
     Tipo = tipo; 
     Longitud = longitud; 
    } 

    public MyData(MyData itemToCopy) 
    { 
     Nombre = itemToCopy.Nombre; 
     Tipo = itemToCopy.Tipo; 
     Longitud = itemToCopy.Longitud; 
    } 

    public string Nombre { get; set; } 
    public string Tipo { get; set; } 
    public int Longitud { get; set; } 

    public override bool Equals(object obj) 
    { 
     if (ReferenceEquals(null, obj)) 
     { 
      return false; 
     } 

     if (ReferenceEquals(this, obj)) 
     { 
      return true; 
     } 

     if (obj.GetType() != this.GetType()) 
     { 
      return false; 
     } 

     return Equals((MyData)obj); 
    } 

    protected bool Equals(MyData other) 
    { 
     return string.Equals(this.Nombre, other.Nombre) && string.Equals(this.Tipo, other.Tipo) && this.Longitud == other.Longitud; 
    } 

    public override int GetHashCode() 
    { 
     unchecked 
     { 
      var hashCode = (this.Nombre != null ? this.Nombre.GetHashCode() : 0); 
      hashCode = (hashCode * 397)^(this.Tipo != null ? Tipo.GetHashCode() : 0); 
      hashCode = (hashCode * 397)^this.Longitud; 
      return hashCode; 
     } 
    } 
} 

2)创建列表的克隆:

List<MyData> mycopy = new List<MyData>(); 

data.ForEach((item)=> 
    { 
     mycopy.Add(new MyData(item)); 
    }); 

3)有了这个代码,您可以那么检查它是否等于:

var isEqual = data.Count == copy.Count; 
if (isEqual) 
{ 
    isEqual = !data.Where((t, i) => !t.Equals(copy[i])).Any(); 
} 
+2

这将创建一个包含相同对象的新列表。 –

+0

当然是的,那是作者想要做的问题。 –

+0

他有吗?他最终会比较相同的对象(在你的查询中:'o'和'p'是相同的对象)。他必须克隆物体,然后才能检测到变化。 –