Linq对象查询集合和返回差异

时间:2015-11-19 10:37:43

标签: c# linq

我一直在努力将一些linq写入对象查询,并想知道你是否可以提供帮助。

UPDATED AND SIMPLIFIED
  1. 根据(Id和OrderNo)输出与tempResult中的值不匹配的所有属性 并将结果放在第三个列表中。
  2. 非常感谢!!!!

    Setup
    
        class Program
        {
            static void Main()
            {
                Customer[] office1 =
                {
                   new Customer {Id = 1,  OrderNo = 1, Name = "Joe", Surname = "Bloggs", City = "London"},
                    new Customer {Id = 2,  OrderNo = 2, Name = "Mark", Surname = "Smith", City = "Manchester"},
                    new Customer {Id = 3,  OrderNo = 3, Name = "Emily", Surname = "Blunt",  City = "Liverpool"},
                };
    
                Customer[] office2 =
                {
                    new Customer {Id = 1,  OrderNo = 1, Name = "Joe", Surname = "Bloggs",  City = "London"},
                    new Customer {Id = 2,  OrderNo = 2, Name = "Mark", Surname = "SmithError", City = "Manchester"},
                    new Customer {Id = 3,  OrderNo = 4, Name = "EmilyError", Surname = "Blunt", City = "LiverpoolError"},
                };
    
                var customerOffice1 = office1.Except(office2);
                var customerOffice2 = office2.Except(office1);
                List<Customer> tmpResult = customerOffice1.Union(customerOffice2).ToList();
    
                //HOW DO i UPDATE THE FOLLOWING LIST WITH RESULT LIKE BELOW.
                List<Difference> diffs = new List<Difference>();
    
                Difference diff1= new Difference { Id = 2, PropertyName = "Surname", OldValue = "Smith", NewValue = "SmithError" };
                diffs.Add(diff1);
                Difference diff2 = new Difference { Id = 3, PropertyName = "Name", OldValue = "Emily", NewValue = "EmilyError" };
                diffs.Add(diff2);
                Difference diff3 = new Difference { Id = 3, PropertyName = "City", OldValue = "Liverpool", NewValue = "LiverpoolError" };
                diffs.Add(diff3);
            }
    
        }
    
        public class Difference
        {
            public int  Id { get; set; } 
            public string PropertyName { get; set; }
            public string OldValue { get; set; }
            public string NewValue { get; set; }
        }
    
        public class Customer : IEquatable<Customer>
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public string Surname { get; set; }
            public string City { get; set; }
            public int OrderNo { get; set; }
    
            public bool Equals(Customer other)
            {
                if (ReferenceEquals(null, other)) return false;
                if (ReferenceEquals(this, other)) return true;
                return string.Equals(Name, other.Name) 
                    && string.Equals(Surname, other.Surname) 
                    && string.Equals(City, other.City);
            }
    
            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((Customer) obj);
            }
    
            public override int GetHashCode()
            {
                unchecked
                {
                    var hashCode = (Name != null ? Name.GetHashCode() : 0);
                    hashCode = (hashCode*397) ^ (Surname != null ? Surname.GetHashCode() : 0);
                    hashCode = (hashCode*397) ^ (City != null ? City.GetHashCode() : 0);
                    return hashCode;
                }
            }
    
            public static bool operator ==(Customer left, Customer right)
            {
                return Equals(left, right);
            }
    
            public static bool operator !=(Customer left, Customer right)
            {
                return !Equals(left, right);
            }
        }
    

2 个答案:

答案 0 :(得分:1)

我做了类似的事情(仅用于匹配的ID,对于另一个您不需要注意的ID):

class Program
{
  static void Main()
  {
    Customer[] office1 =
            {
               new Customer {Id = 1,  OrderNo = 1, Name = "Joe", Surname = "Bloggs", City = "London"},
                new Customer {Id = 2,  OrderNo = 2, Name = "Mark", Surname = "Smith", City = "Manchester"},
                new Customer {Id = 3,  OrderNo = 3, Name = "Emily", Surname = "Blunt",  City = "Liverpool"},
                new Customer {Id = 5,  OrderNo = 6, Name = "XX", Surname = "YY",  City = "ZZ"},
            };

    Customer[] office2 =
            {
                new Customer {Id = 1,  OrderNo = 1, Name = "Joe", Surname = "Bloggs",  City = "London"},
                new Customer {Id = 2,  OrderNo = 2, Name = "Mark", Surname = "SmithError", City = "Manchester"},
                new Customer {Id = 3,  OrderNo = 4, Name = "EmilyError", Surname = "Blunt", City = "LiverpoolError"},
                new Customer {Id = 4,  OrderNo = 5, Name = "X", Surname = "Y", City = "Z"},
            };

    var customerOffice1 = office1.Except(office2);
    var customerOffice2 = office2.Except(office1);
    var diffIds = customerOffice1.Select(o => o.Id)
              .Intersect( 
                  customerOffice2.Select(o => o.Id) 
              );
    var difList = diffIds
      .SelectMany(i => customerOffice1.SingleOrDefault(o => o.Id == i)
      .GetDifference(customerOffice2.SingleOrDefault(o => o.Id == i)));
     // LinqPad
     // difList.Dump();
  }
}

public class Difference
{
  public int Id { get; set; }
  public string PropertyName { get; set; }
  public string OldValue { get; set; }
  public string NewValue { get; set; }
}

public class Customer : IEquatable<Customer>
{
  public int Id { get; set; }
  public string Name { get; set; }
  public string Surname { get; set; }
  public string City { get; set; }
  public int OrderNo { get; set; }

  public List<Difference> GetDifference(Customer other)
  {
    return this.GetType().GetProperties()
      .Where(t => t.Name != "Id" && 
        t.GetValue(this).ToString() != t.GetValue(other).ToString() )
      .Select(t => new Difference { 
        Id = this.Id,
        PropertyName = t.Name,
        OldValue = t.GetValue(this).ToString(), 
        NewValue = t.GetValue(other).ToString()
        }).ToList();
  }

  public bool Equals(Customer other)
  {
    if (ReferenceEquals(null, other)) return false;
    if (ReferenceEquals(this, other)) return true;
    return string.Equals(Name, other.Name)
        && string.Equals(Surname, other.Surname)
        && string.Equals(City, other.City);
  }

  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((Customer)obj);
  }

  public override int GetHashCode()
  {
    unchecked
    {
      var hashCode = (Name != null ? Name.GetHashCode() : 0);
      hashCode = (hashCode * 397) ^ (Surname != null ? Surname.GetHashCode() : 0);
      hashCode = (hashCode * 397) ^ (City != null ? City.GetHashCode() : 0);
      return hashCode;
    }
  }

  public static bool operator ==(Customer left, Customer right)
  {
    return Equals(left, right);
  }

  public static bool operator !=(Customer left, Customer right)
  {
    return !Equals(left, right);
  }
}

编辑: 结果:

Id PropertyName OldValue  NewValue

2 Surname       Smith     SmithError 
3 Name          Emily     EmilyError 
3 City          Liverpool LiverpoolError 
3 OrderNo       3         4 

编辑: 仅q1的现有ID和OrderNo:

var q1 = customerOffice1.Where(o => 
  office2.Any( o2 => o2.Id == o.Id && o2.OrderNo == o.OrderNo ))
  .Select(o => o.Id);
var difList = q1
  .SelectMany(i => customerOffice1.SingleOrDefault(o => o.Id == i)
  .GetDifference(customerOffice2.SingleOrDefault(o => o.Id == i)));

这个更短了恕我直言:

var xxx = (from c1 in office1
          from c2 in office2
          where 
            c1.Id == c2.Id && 
            c1.OrderNo == c2.OrderNo &&
            c1 != c2
          select c1.GetDifference(c2)).SelectMany(d=>d);

答案 1 :(得分:0)

我觉得我能够回答你问题的第一部分:

  

查询1根据(Id和OrderNo)输出与tempResult中的值不匹配的所有属性

var diffs = office1.Zip(office2, (first, second) => Tuple.Create(first, second))
.Where(x => x.Item1.Id != x.Item2.Id || x.Item1.OrderNo != x.Item2.OrderNo);

这将返回一组客户元组,这些客户没有匹配的ID或订单号 - 而元组包含不匹配客户的数据。

我担心第二点仍然不清楚,所以我无法帮助。