2012-11-21 73 views
3

我想比較看起來像這樣的循環通過包含變量

public class Order 
{ 
     public string KundNummer, KundNamn, ErReferens, VarReferens, KontraktsNummer, Betvillk, Levvillk, Levsatt, Speditor, 
      Resenh, Projekt, OrderDatum, LeveransDatum, ErtOrdernr, LagerbokfDatum, KundPostAdr, KundPostAdr2, KundGLN, KundPostnr, 
      KundOrt, KundLandKod, KundLand, KundVATnr, KundDistrikt, KundSaljare, KundText1, KundText2, KundText3, KundSprak, 
      KundValuta, KundRabattAvtal, KundRabattAvtalBenamning, KundPrislista, KundPrislistaBenamning, KundALnamn, KundALpostAdr, KundALpostAdr2, KundALGLN, KundALpostnr, KundALort, 
      KundALlandKod, KundALland; 
     public double OrderNummer, Fakturarabatt, Frakt, Expavg, Brutto, Netto, ExklMoms, Totalt, Moms, Avrundn, KundValutaKurs, KundValutaEnhet; 
     public int EUPeriodSamman, InklMoms, EjKlar, Levererad, Malukerad, BestallningSkapad, Ordererk, 
      Plocklista, Foljesedel, ExtraOrderdokument, Restorder, Faktura, KundSparaText, KundExport, KundRantefakturering, KundKravbrev, 
      KundKravavgift, KundRestnoteraEj, KundSamlingsfakturera; 
    } 

我想比較這類記錄它在我的數據庫,改變字段的兩個對象兩大類一類。

public string OrderUppdateraOrder(Order order) 
    { 
     Order OrderToCompare = new Order(); 
     OrderToCompare = OrderVisaOrderInformation(order.OrderNummer); 

     //then the code goes on to make the changes to the database from the class order 
     //while OrdertoComapre still have the values from before this function was called 
    } 

所以是有可能遍歷這些類和它們進行比較或做我有一個如果寫在我的班級每一個變量? :)

或者將其轉換爲列表?我不知道? :P

謝謝你的答案

+1

這可能會幫助你:http://stackoverflow.com/questions/6240385/can-i-use-reflection-to-get-an-existing-variable-by-providing-its-name 但是,這是不好的做法。 – looper

+0

您可以隨時使用反射並將實例上的每個屬性與其他屬性進行比較。但取決於您使用的是什麼ORM,您可能已經建立了對發現已更改的所有內容的支持。要使用refleciton檢查我的博客文章:http://blog.filipekberg.se/2011/10/08/exploring-reflection-finding-a-value-in-any-of-the-objects-properties/ *請記住,雖然使用反射可以導致性能penelities!* –

+0

我的上帝......是否有任何可能性您的這個類進入較小的組件類......而是一個規範化的形式...... :) – bonCodigo

回答

3

我想登錄,如果是有區別和日誌的區別是這樣的CUSTOMERNUMBER:從456改到345

最好的選擇可能只是使用反射來檢索公共屬性和字段,比較它們。這將有比較少的代碼,但會有性能開銷。您可以使用工具,如FastMember大大減少開銷:

static class Program { 
    static void Main() 
    { 
     Order o1 = new Order { Resenh = "abc" }, 
       o2 = new Order { Resenh = "abc" }; 
     ShowDiffs(o1, o2); // {nothing} 
     o2.Resenh = "def"; 
     ShowDiffs(o1, o2); // Resenh changed from abc to def 
    } 
    static void ShowDiffs<T>(T x, T y) 
    { 
     var accessor = TypeAccessor.Create(typeof(T)); 
     if (!accessor.GetMembersSupported) throw new NotSupportedException(); 
     var members = accessor.GetMembers(); 

     foreach (var member in members) 
     { 
      object xVal = accessor[x, member.Name], 
        yVal = accessor[y, member.Name]; 
      if (!Equals(xVal, yVal)) 
      { 
       Console.WriteLine("{0} changed from {1} to {2}", 
        member.Name, xVal, yVal); 
      } 
     } 
    } 
} 
+1

FastMember在這裏,順便說一句:http://nuget.org/packages/FastMember –

+0

@LukeHennerley是......它會。通用類型可以從提供給方法調用的參數中推斷出來。 –

+0

這看起來像我想要的東西,但我只是檢查我不太瞭解的東西。所以請耐心等待我的解答!^^ – Dendei

1

也許這種方法可以幫助你

public class Order 
{ 
    public string KundNummer, KundNamn, ErReferens, VarReferens, KontraktsNummer, Betvillk, Levvillk, Levsatt, Speditor, 
     Resenh, Projekt, OrderDatum, LeveransDatum, ErtOrdernr, LagerbokfDatum, KundPostAdr, KundPostAdr2, KundGLN, KundPostnr, 
     KundOrt, KundLandKod, KundLand, KundVATnr, KundDistrikt, KundSaljare, KundText1, KundText2, KundText3, KundSprak, 
     KundValuta, KundRabattAvtal, KundRabattAvtalBenamning, KundPrislista, KundPrislistaBenamning, KundALnamn, KundALpostAdr, KundALpostAdr2, KundALGLN, KundALpostnr, KundALort, 
     KundALlandKod, KundALland; 
    public double OrderNummer, Fakturarabatt, Frakt, Expavg, Brutto, Netto, ExklMoms, Totalt, Moms, Avrundn, KundValutaKurs, KundValutaEnhet; 
    public int EUPeriodSamman, InklMoms, EjKlar, Levererad, Malukerad, BestallningSkapad, Ordererk, 
     Plocklista, Foljesedel, ExtraOrderdokument, Restorder, Faktura, KundSparaText, KundExport, KundRantefakturering, KundKravbrev, 
     KundKravavgift, KundRestnoteraEj, KundSamlingsfakturera; 

    public static bool operator ==(Order left, Order right) 
    { 
     foreach (var field in left.GetType().GetFields()) 
     { 
      object valueLeft = field.GetValue(left); 
      object valueRight = field.GetValue(right); 

      if (!object.Equals(valueLeft, valueRight)) 
       return false; 
     } 

     return true; 
    } 

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

} 
+0

'object.Equals(valueLeft,valueRight)'比使用比較器和檢查0更合適;另外,如果你看到評論,意圖是成員細節的變化 –

+0

這是真的馬克,編輯。 – joseangelmt

1

從我如何理解你行 - 你有這將retreive從數據庫中Order對象,哪些是你可以從已intially有一個Order對象的方法數據庫,但修改。你要檢查,如果一個或多個訂單有變化就問:

因爲如果Database.A等於Your.A等每個訂單

我會把你的支票到一個地方,並覆蓋方法Equals

public class Order 
    { 
    public int Id; 
    public string SomeProp; 
    public string AnotherProp; 
    public override bool Equals(object obj) 
    { 
     Order orderToCompare = (Order)obj; 
     return (SomeProp == orderToCompare.SomeProp && AnotherProp == orderToCompare.AnotherProp); 
    } 
    } 

那麼有兩個方法,一個用於更新一個訂單,一個用於更新許多訂單。

private void UpdateOrder(Order o) 
{ 
    //Get the corresponding order from the database (I suspect Entity Framework here in order to get an object?) 
    Order dbOrder = OrderVisaOrderInformation(o.Id); 
    if (dbOrder.Equals(o)) 
    { 
    //Do some update 
    } 
} 
private void UpdateManyOrders(List<Order> orders) 
{ 
    var dbOrders = (from order in orders 
        select OrderVisaOrderInformation(order.Id)); 
    List<Order> ordersToUpdate = dbOrders.Where(x => !x.Equals(orders.First(y => y.Id == x.Id))).ToList(); 
    foreach (Order orderToUpdate in ordersToUpdate) 
    { 
    //Update the order 
    } 
} 

這可能是錯誤的,但從我如何理解你的問題,這是你想要做的。

+0

如果你看到評論,要求是成員細節的變化。另外:如果你重寫'Equals',你也應該重載'GetHashCode' - 對於很多高維護的成員 –

+0

@MarcGravell我看到......我開始做這個答案,而許多評論正在發生。謝謝。 – LukeHennerley

+0

我可以聯繫...我有一個刪除的答案做一個優化的'表達式'比較; p –