Funky
Funky

Reputation: 13612

C# Abstracting methods

I have a set of methods, that take in dates and a bool. These methods then use some SQL then pass it on to another method and return a list. Each method is pretty much the same with the exception of the SQL and the List returned. Now I know there is a better way do these methods but I'm not sure how.

Does anyone have any ideas as to how I can abstract this or use a better design as the methods are almost identical?

Here is the 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));   
}

Upvotes: 2

Views: 220

Answers (6)

Heinzi
Heinzi

Reputation: 172280

You could shorten your functions considerably. For example, instead of

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));
}

you could simply write

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));
}

That basically reduces your function to the stuff that really matters: The SQL and the name of the serialization function.

Upvotes: 2

Krumelur
Krumelur

Reputation: 33048

You could have one base class all your ENT_* classes inherit from. Then make one method List<ENT_Base>GetData(yourParams). Create a factory method which gets you a list of entities depending on the type of ENT_Base. Your GetData() calls that and returns it. You will not get around a switch-case or if-then to figure out which kind of entities you have to return.

Upvotes: 0

Baltasarq
Baltasarq

Reputation: 12212

You can create a class SqlRetriever, and then subclass each one with the specific SQL message to send.

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

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

Another possibility, involving less classses, with a worse design is the following one:

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;
        }
}

Upvotes: 1

Tesserex
Tesserex

Reputation: 17314

It looks like you have an opportunity to make a generic method. I apologize in advance if I have syntax errors.

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));    
}

Notice a few things I did:

  1. The generic method has a constraint that T is a subclass of ENT_Data, a type I just made up.
  2. I gave ENT_Data types a table field, for use in your query.
  3. The Converter.Serialize methods have also been made generic in a similar manner.

If I missed anything important just let me know.

Upvotes: 2

Kevin
Kevin

Reputation: 25269

If you store your sql statements and a delegate method in a map where the key is some type T, then make your method generic (method takes type T and returns List of T), you can do a map lookup to get the correct sql statements and delegate method.

Upvotes: 0

anthonyvd
anthonyvd

Reputation: 7590

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)); 
        }

From that point on, you call

GetData<ENT_whatever>() 

only.

Upvotes: 1

Related Questions