2013-08-29 27 views
9

Tôi đã xóa Internet để thử và tìm giải pháp cho điều này, và có lẽ tôi sẽ không thực hiện đúng cách này.So sánh hai bộ dữ liệu - Tìm các thay đổi - LINQ

Tôi cần so sánh hai tập dữ liệu, giống hệt nhau trong cấu trúc và muốn tìm các đối tượng mới và đã thay đổi (sử dụng LINQ).

Sử dụng những gì tôi tìm thấy tại CodeProject, tôi có thể kéo danh sách các mục đã thay đổi, nhưng điều này được thực hiện bằng cách mã hóa cứng mỗi cột (và sẽ có nhiều) và kiểm tra các giá trị giống nhau:

var updRec = from u in updated 
      join o in orig 
       on u.KeyValue equals o.KeyValue 
      where 
       (o.Propery1 != u.Propery1) || 
       (o.Propery2 != u.Propery2) 
      select new record 
      { 
       KeyValue = u.KeyValue, 
       Propery1 = u.Propery1, 
       Propery2 = u.Propery2 , 
       RecordType = "mod" // Modified 
      }; 

tôi có thể sử dụng sự giúp đỡ với 2 điều:

  1. có cách nào hiệu quả hơn để lặp qua từng cột, như tôi đã có kế hoạch bổ sung thêm nhiều tính chất nữa mà tôi cần phải so sánh ? Phải có cách tốt hơn để kiểm tra động 2 bộ dữ liệu giống hệt nhau để thay đổi.
  2. Tôi làm cách nào để xem thích hợp đã thay đổi? Ví dụ: tạo danh sách 'Thuộc tính, OriginalValue, Cập nhật giá trị' cho tất cả các mục không giống nhau?

Hy vọng điều đó sẽ giải thích rõ. Xin vui lòng chỉ cho tôi những cách khác để xử lý kịch bản này nếu tôi không nhìn vào nó một cách chính xác.

+0

Bạn có thể ghi đè 'Equals()' trong đối tượng 'record' của bạn và thực hiện so sánh ở đó. Sau đó, bạn có thể thay đổi mệnh đề 'where' thành' where o.Equals (u) '. Nhưng đó chỉ là di chuyển so sánh với một nơi gói gọn hơn. Nếu bạn muốn tự động hóa nhiều hơn, bạn có thể sẽ cần phải sử dụng sự phản chiếu. –

+0

Bạn có thể phải liệt kê tất cả các cột, có lẽ tôi chỉ không biết một cách tốt hơn nhưng tôi biết trong TSQL bạn phải liệt kê tất cả các cột để so sánh deltas mặc dù có một số thủ thuật groupby để so sánh nhanh hơn. –

+0

Làm cách nào để xác định thay đổi? Gần đây tôi đã gặp phải vấn đề tương tự và tôi đã tạo một phương thức kết hợp 2 đối tượng cùng loại, lấy giá trị từ đối tượng thuộc tính không rỗng hoặc mặc định và nó cũng cung cấp tùy chọn để chọn đối tượng ưu tiên, trong trường hợp cả hai thuộc tính đều có giá trị. Nếu đó là điều bạn có thể muốn, hãy cho tôi biết và tôi sẽ đăng câu trả lời bằng mã và giải thích tốt hơn. –

Trả lời

0
  1. Nhanh hơn nhưng bạn sẽ cần phải duy trì mã nếu bạn thêm thuộc tính mới là viết so sánh tùy chỉnh và sử dụng cách tiếp cận của bạn.
  2. chậm phản xạ sử dụng để đi qua tất cả các thuộc tính và so sánh chúng động

    IDictionary<string, Tuple<object, object>> GetDifferentProperties<T>(T keyValue1, T keyValue2) 
    { 
        var diff = new Dictionary<string, object>(); 
        foreach (var prop in typeof(T).GetProperties(BindingFlags.Public)) 
        { 
         var prop1Value = prop.GetValue(keyvalue1); 
         var prop2Value = prop.GetValue(keyValue2); 
         if (prop1Value != prop2Value) 
         diff.Add(prop.Name, Tuple.Create(prop1Value, prop2Value)); 
        } 
        return diff; 
    } 
    

và sau đó trong bạn mã

var = results = (from u in updated 
        join o in orig 
        select new 
        { 
         Value1 = o.KeyValue, 
         Value2 = u.KeyValue 
        }).ToArray() 
        .Select(x => GetDifferentProperties(x.Value1, x.Value2)) 
        .Select(DoSomestufWithDifference); 
1

Bạn có thể sử dụng LINQ Trừ (phương pháp mở rộng). Điều đó trả về mọi thứ trong một danh sách ngoại trừ những gì nằm trong danh sách thứ hai.

var orignalContacts = GetOrignal(); 
var updatedContacts = GetUpdated(); 

var changedAndNew = updatedContacts.Except(orignalContacts); 
var unchanged  = orignalContacts.Except(updatedContacts); 

Tùy thuộc vào nhà cung cấp dữ liệu bạn có thể cần phải vượt qua Equals() và GetHashCode() trên các đối tượng của bạn.