2011-02-24 3 views
2

J'ai un ensemble de méthodes, qui prennent des dates et un bool. Ces méthodes utilisent ensuite du SQL puis le transmettent à une autre méthode et retournent une liste. Chaque méthode est à peu près la même à l'exception du SQL et de la liste retournée. Maintenant, je sais qu'il existe une meilleure façon de faire ces méthodes, mais je ne sais pas comment.C# Méthodes de résumé

Est-ce que quelqu'un a des idées quant à la façon dont je peux abstraite ceci ou utiliser une meilleure conception que les méthodes sont presque identiques?

Voici le code:

private List<ENT_Message> GetMessageData(DateTime? startDate, DateTime? endDate, bool IsSelectAll) 
{ 
    List<ENT_Message> ret = new List<ENT_Message>(); 
    string sql = ""; 

    if (IsSelectAll) 
    { 
     sql = "select * from tbl_message"; 
    } 
    else 
    { 
     sql = " Select * from tbl_message where created_Date between @start_Date and @end_date"; 
    } 

    return Converter.SerializeToMessageList(this.GetData(startDate, endDate, IsSelectAll, sql));     
} 

private List<ENT_SensorData> GetSensorData(DateTime? startDate, DateTime? endDate, bool IsSelectAll) 
{ 
    List<ENT_SensorData> ret = new List<ENT_SensorData>(); 
    string sql = ""; 

    if (IsSelectAll) 
    { 
     sql = "select * from tbl_sensor_data"; 
    } 
    else 
    { 
     sql = "select * from tbl_sensor_data where Timestamp between @start_date and @end_Date"; 
    } 

    return Converter.SerializeToSensorDataList(this.GetData(startDate, endDate, IsSelectAll, sql)); 
} 

private List<ENT_SensorDataEvent> GetSensorDataEvents(DateTime? startDate, DateTime? endDate, bool IsSelectAll) 
{ 
    List<ENT_SensorDataEvent> ret = new List<ENT_SensorDataEvent>(); 
    string sql = ""; 

    if (IsSelectAll) 
    { 
     sql = "select * from tbl_sensor_data_event"; 
    } 
    else 
    { 
     sql = "select * from tbl_sensor_data_event where start_time between @start_date and @end_Date"; 
    } 

    return Converter.SerializeToSensorEventDataList(this.GetData(startDate, endDate, IsSelectAll, sql)); 
} 

private List<ENT_SensorDataState> GetSensorDataState(DateTime? startDate, DateTime? endDate, bool IsSelectAll) 
{ 
    List<ENT_SensorDataState> ret = new List<ENT_SensorDataState>(); 
    string sql = ""; 

    if (IsSelectAll) 
    { 
     sql = "select * from tbl_sensor_data_state"; 
    } 
    else 
    { 
     sql = "select * from tbl_sensor_data_state where start_time between @start_date and @end_Date"; 
    } 

    return Converter.SerializeToSensorDateStateList(this.GetData(startDate, endDate, IsSelectAll, sql)); 
} 

private List<ENT_WorkOrder> GetWorkOrders(DateTime? startDate, DateTime? endDate, bool IsSelectAll) 
{ 
    List<ENT_WorkOrder> ret = new List<ENT_WorkOrder>(); 
    string sql = ""; 

    if (IsSelectAll) 
    { 
     sql = "select * from tbl_workorder"; 
    } 
    else 
    { 
     sql = "select * from tbl_sensor_data_state where completed_date between @start_date and @end_Date"; 
    } 

    return Converter.SerializeToWorkOrderList(this.GetData(startDate, endDate, IsSelectAll, sql)); 
} 
+3

Pourquoi n'avez-vous pas simplement ajouté le code dans le cadre de votre question? – RQDQ

+0

@RQDQ: Le code est un peu long et rendrait la question moins lisible. Je ne vois aucun problème à ce que ce soit ailleurs pour plus de clarté. –

+0

@Henk si vous regardez le code, vous verrez quelle liste est retournée – Funky

Répondre

2

Vous pouvez réduire considérablement vos fonctions.Par exemple, au lieu de

private List<ENT_SensorDataState> GetSensorDataState(DateTime? startDate, DateTime? endDate, bool IsSelectAll) 
{ 
    List<ENT_SensorDataState> ret = new List<ENT_SensorDataState>(); 
    string sql = ""; 

    if (IsSelectAll) 
    { 
     sql = "select * from tbl_sensor_data_state"; 
    } 
    else 
    { 
     sql = "select * from tbl_sensor_data_state where start_time between @start_date and @end_Date"; 
    } 

    return Converter.SerializeToSensorDateStateList(this.GetData(startDate, endDate, IsSelectAll, sql)); 
} 

vous pouvez simplement écrire

private List<ENT_SensorDataState> GetSensorDataState(DateTime? startDate, DateTime? endDate, bool IsSelectAll) 
{ 
    string sql = "select * from tbl_sensor_data_state" 
       + (IsSelectAll ? "" : "where start_time between @start_date and @end_Date"); 

    return Converter.SerializeToSensorDateStateList(this.GetData(startDate, endDate, IsSelectAll, sql)); 
} 

Cela réduit essentiellement votre fonction à la substance qui importe vraiment: Le SQL et le nom de la fonction de sérialisation.

+0

J'aime beaucoup ça! – Funky

+0

Par conséquent, vous êtes toujours en train de copier/coller chaque méthode. Les méthodes génériques ou abstraites pourraient donner des résultats avec moins de répétition. – Abel

+0

@Abel: Vrai. Cependant, le SQL est différent dans chaque fonction, donc * cette partie * ne peut pas être généralisée. – Heinzi

1
private List<T> GetData<T>(DateTime? startDate, DateTime? endDate, bool IsSelectAll) 
     { 
      List<T> ret = new List<T>(); 

      string tableName = "";//Select the table name based on T here 
      string sql = ""; 

      if (IsSelectAll) 
      { 
       sql = "select * from tbl_sensor_data"; 
      } 
      else 
      { 
       sql = "select * from tbl_sensor_data where Timestamp between @start_date and @end_Date"; 
      } 
      //Build your list using the appropriate converter based on T here   
      return Converter.SerializeToSensorDataList(this.GetData(startDate, endDate, IsSelectAll, sql)); 
     } 

A partir de ce moment-là, vous appelez

GetData<ENT_whatever>() 

seulement.

+0

'tbl_sensor_data' n'est pertinent que pour une méthode - il faut vraiment dépendre de T. –

0

Si vous stockez vos instructions sql et une méthode déléguée dans une map où la clé est de type T, alors générez votre méthode générique (la méthode prend le type T et renvoie List of T), vous pouvez effectuer une recherche de carte pour obtenir les instructions sql correctes et la méthode déléguée.

2

Il semble que vous avez la possibilité de faire une méthode générique. Je m'excuse d'avance si j'ai des erreurs de syntaxe.

private List<T> GetData<T>(DateTime? startDate, DateTime? endDate, bool IsSelectAll) where T : ENT_Data 
{ 
    List<T> ret = new List<T>(); 
    string sql = ""; 

    if (IsSelectAll) 
    { 
     sql = "select * from " + T.table; 
    } 
    else 
    { 
     sql = " Select * from " + T.table + " where created_Date between @start_Date and @end_date"; 
    } 

    return Converter.Serialize<T>(this.GetData(startDate, endDate, IsSelectAll, sql));  
} 

avis quelques choses que j'ai:

  1. La méthode générique a une contrainte que T est une sous-classe de ENT_Data, un type que je viens d'inventer.
  2. Je donnai types ENT_Data un champ table, pour une utilisation dans votre requête.
  3. Les méthodes Converter.Serialize ont également été rendues génériques d'une manière similaire.

Si je manqué quelque chose d'important me laisser simplement savoir.

+0

Vous ne pouvez pas contraindre T à avoir un champ statique/propriété appelée 'table'. –

+0

Vous avez raison, ma mauvaise. Vous devez créer une instance de T et obtenir le nom de la table. – Tesserex

+0

Juste une pensée pour rendre cela plus générique (écrire une fois): Utilisez une interface parent 'IEnt_Data' avec la propriété' table'. Ensuite, ayez votre classe concrète de base 'ENT_Data' une méthode statique' ENT_Data.Create ', qui renvoie une instance de ce type. Ensuite, vous pouvez l'appeler avec 'ENT_Data.Create () .table'. – Abel

1

Vous pouvez créer un SqlRetriever de classe, puis sous-classe chacun avec le message SQL spécifique à envoyer.

class SqlRetriever { 
    public abstract void SendSqlCmd(); 
    public ArrayList List { 
     get; set; 
    } 
} 

class SqlRetrieverXXX 
    public const string SqlCmd = " ... "; 
    public override void SendSqlCmd() 
    { 
     /* ... */ 
    } 
} 

Une autre possibilité, impliquant moins CLASSIFICATION DES, avec un design pire est la suivante:

class SqlRetriever { 
     public const string SQLCmd1 = "..."; 
     public const string SQLCmd2 = "..."; 

     public void SendSqlCmd(string sqlcmd) 
     { 
      /*Send the SQL Cmd and store the result in the list */ 
     } 

     public ArrayList List { 
      get; set; 
     } 

     public static ArrayList DoSqlCmd(string sqlCmd) 
     { 
      var obj = new SqlRetriever(); 

      obj.SendSqlCmd(sqlCmd); 

      return obj.List; 
     } 
} 
0

Vous pourriez avoir une classe de base tous vos ENT_ * classes héritent de. Ensuite, créez une méthode. Liste <ENT_Base> GetData (yourParams). Créez une méthode usine qui vous permet d'obtenir une liste d'entités en fonction du type de ENT_Base. Votre GetData() l'appelle et le renvoie. Vous ne contournerez pas un cas-switch ou si-alors pour savoir quel genre d'entités vous devez retourner.