2014-12-04 17 views
6

Ho molti metodi che seguono in parti grandi lo stesso algoritmo e idealmente voglio essere in grado di effettuare chiamate a un metodo generico che elimina un sacco di duplicazione del codice.Problemi con una grande quantità di duplicazione del codice

Ho tonnellate di metodi come quelli qui sotto, vorrei in modo ottimale vogliono essere in grado di chiamare solo Save<SQLiteLocation>(itemToSave); ma ho una grande quantità di problemi in quanto che i metodi SQLiteConnection.Find<T> non accettare un tipo di dato astratto come T in generici.

C'è un modo per aggirare questo, se potessi farlo riparare vorrei salvare fino a 150 righe di codice

Ecco il mio codice:

public bool SaveLocation(ILocation location, ref int primaryKey) 
    { 
     var dbConn = new SQLiteConnection (dbPath); 

     SQLiteLocation itemToSave = new SQLiteLocation(); 
     itemToSave.LocationName = location.LocationName; 
     itemToSave.Latitude = location.Latitude; 
     itemToSave.Longitude = location.Longitude; 
     itemToSave.PrimaryKey = location.PrimaryKey; 

    ---------------------------------------------------------------------------------------- 

     SQLiteLocation storedLocation = dbConn.Find<SQLiteLocation> 
             (x => x.PrimaryKey == location.PrimaryKey); 

     if (storedLocation != null) 
     { 
      dbConn.Update(itemToSave); 
      return true; 
     } 

     else if (storedLocation == null) 
     { 
      dbConn.Insert(itemToSave); 
      primaryKey = itemToSave.PrimaryKey; 
      return true; 
     } 
     return false; 
    } 

Ed ecco un altro metodo vedere come il codice in entrambi i metodi indicati mia linea tratteggiata è fondamentalmente la stessa cosa

public bool SaveInvitation(IInvitation invitation, ref int primaryKey) 
    { 
     var dbConn = new SQLiteConnection(dbPath); 

     SQLiteInvitation itemToSave = new SQLiteInvitation(); 
     itemToSave.GroupName = invitation.GroupName; 
     itemToSave.InviterName = invitation.InviterName; 
     itemToSave.ParseID = invitation.ParseID; 
     itemToSave.GroupParseID = invitation.GroupParseID; 
     itemToSave.PrimaryKey = invitation.PrimaryKey; 

--------------------------------------------------------------------------------------- 

     SQLiteInvitation storedInvitation = dbConn.Find<SQLiteInvitation> 
              (x => x.PrimaryKey == invitation.PrimaryKey); 

     if (storedInvitation != null) 
     { 
      dbConn.Update(itemToSave); 
      return true; 
     } 
     else if (storedInvitation == null) 
     { 
      dbConn.Insert(itemToSave); 
      primaryKey = itemToSave.PrimaryKey; 
      return true; 
     } 
     return false; 
    } 
+0

È possibile utilizzare automapper o qualcosa di simile per spostare le proprietà. Inoltre, se sposti 'itemToSave' dal metodo e lo passi come parametro, allora credo che potresti rendere generico il resto del codice. –

+0

Hai considerato di esaminare gli alberi di espressione per creare l'istruzione 'Trova '? –

+0

'storedX' è o' null' o no, quindi non è necessario usare 'else if'. A causa di ciò, non restituirai mai false, quindi potresti rimuovere il valore restituito. Sinistra è 'if (storedX! = Null) {dbConn.Update (itemToSave); } else {dbConn.Insert (itemToSave); primaryKey = itemToSave.PrimaryKey; } '. 3 righe rimosse proprio lì – Default

risposta

0

Per qualche ragione ha generato un'eccezione non supportato quando ho usato:

T storedItem = dbConn.Find<T>(x => x.PrimaryKey == item.PrimaryKey); 

Il codice sotto fissato i miei guai, però, grazie per l'aiuto a tutti, mi piace questo sito! Inoltre ho aggiunto un altro vincolo sulle T visto che T deve essere un tipo non astratto e un'interfaccia è solo che suppongo

private void SaveItem<T>(T item, ref int primaryKey) 
     where T : ISQLiteClass, new() 
    { 
     var dbConn = new SQLiteConnection(dbPath); 

     T storedItem = dbConn.Find<T>(primaryKey); 

     if (storedItem != null) 
     { 
      dbConn.Update(item); 
     } 
     else if (storedItem == null) 
     { 
      dbConn.Insert(item); 
      primaryKey = item.PrimaryKey; 
     } 
    } 
1

non dovresti essere in grado di fare qualcosa del genere: Nota: IComm onInterface è tutto ciò che è comune tra tutte le classi consentite che vorresti usare come T. Preferibilmente, guardando il tuo codice, un'interfaccia o una classe che espone la proprietà PrimaryKey.

public bool SaveItem<T>(T item, ref int primaryKey) where T : ICommonInterface, new() 
{ 
    var dbConn = new SQLiteConnection(dbPath); 


    T storedItem = dbConn.Find<T>(x => x.PrimaryKey == item.PrimaryKey); 

    if (storedItem != null) 
    { 
     dbConn.Update(item); 
     return true; 
    } 
    else if (storedItem == null) 
    { 
     dbConn.Insert(item); 
     primaryKey = item.PrimaryKey; 
     return true; 
    } 
    return false; 
} 

MODIFICA: aggiunto il nuovo vincolo() al metodo.

+0

Hai ragione hai corretto il mio codice e hai salvato le mie molte molte righe di codice – Guano

+0

In realtà sembra che fossi troppo avventato, ottengo questo errore: \t \t \t 'T 'deve essere un tipo non astratto con un costruttore pubblico senza parametri per utilizzarlo come parametro' T 'nel tipo generico o nel metodo' SQLite.SQLiteConnection.Find (System.Linq.Expressions.Expression >) '(CS0310) (ShoppingAssistant) – Guano

+0

Vedere la risposta modificata. Aggiungi un nuovo vincolo() al metodo. ex: dove T: ICommonInterface, new() – gmiley

Problemi correlati