0

I have a task to develop a console application that is a recon of values from a few tables in the DB. I have all the queries that I need for each value that is required and understand the logic on how the values will interact. The challenge I have is the best method to retrieve and store these values.

I have researched and successfully been able to create the static method to retrieve a single value from a single SQL query but I'm curious about the best method:

  1. Create multiple methods to retrieve each value (upwards of 15 different select statements) summarised below (not complete code)

    static double total1(int arg)
        {
            using (SqlConnection connection = new SqlConnection(connectionString))
            {
                connection.Open();
                SqlCommand command1 = new SqlCommand(commandText1, connection));
                return(response);
            }
    }
    static double total2(int arg)
        {
            using (SqlConnection connection = new SqlConnection(connectionString))
            {
                  connection.Open();
                SqlCommand command2 = new SqlCommand(commandText2, connection));
                return(response);
        }
    }
    
  2. Try to combine all select statements in a single method (I've been unsuccessful here) summarised below (not complete code)

    using (SqlConnection connection = new SqlConnection(connectionString))
    {
        connection.Open();
        using (SqlCommand command1 = new SqlCommand(commandText1, connection))
        {
        }
        using (SqlCommand command2 = new SqlCommand(commandText2, connection))
        {
        }
        // etc
    }
    
  3. Create stored procedures in SQL and execute them and pass the parameters via the c# console app

I think method 1 is going to be taxing on the server as it would require the connection to open and close multiple times (although I don't know if that's as big a issue as I think it is). Method 2 seems more reasonable although I've followed the concepts here and I get stuck when trying to get the output of the commands (I'm using return). Method 3 seems smarter to me although I'd still be in a position where I need to choose between methods 1 & 2 to execute the SP's.

I would really appreciate advice and guidance here, I'm new to C# so this is a steep learning curve when tutorials don't cover the sort of thing (or at least I can't define my problem properly)

Community
  • 1
  • 1
Daniel
  • 2,167
  • 5
  • 23
  • 44
  • 1
    By default, the .net connection is 'pooled' - when you open it for the first time, there is an open database connection overhead, but when you 'close' the connection (which you are correctly doing here via the using statement) - it returns to the connection pool, and is not really closed to the process - next time a similar connection is required, it gets pulled back out of the pool with a much lower overhead – Cato Nov 02 '16 at 10:00
  • Maybe you can state how those values stored (15 different tables? All in different structures?), and how you work with that values after retrieved? So that we can understand more and give you more better option. – Prisoner Nov 02 '16 at 10:01
  • if there are 15 single values, then you probably would be able to retrieve them all at once using single SQL command, if you want 15 separate SQL strings, you can still execute them all at once and populate a dataset, or you could also take the same .net command, open a datareader and process each SQL via DataReader.NextResult – Cato Nov 02 '16 at 10:05
  • @AndrewDeighton that makes sense and is far more efficient (I had hoped it was the case). The question is: is it better to use the approach in 1 or in 2? – Daniel Nov 02 '16 at 10:05
  • @Alex there's about 8 different tables, and 40 separate values I need to get, using 15 different select & join statements (some of the other values are calculations on the retrieved data). So one select may include a parameter that another doesn't. I honestly don't mind doing it the long way but I want to be sure I'm not doing it the wrong way – Daniel Nov 02 '16 at 10:06
  • 3
    I think a lot of programmers would prefer the approach in (1), as it seems to provide more object oriented and ordered code. There's probably an argument for 3 as well ,your stored procedure can receive all parameters needed - it could populate stored procedure variables, then it could return these in a single select if you wanted e.g. SELECT &val1 as FirstVal, &val2 AnotherVal, ...... – Cato Nov 02 '16 at 10:14
  • I'd go with @AndrewDeighton approach 3 where the parameters are passed to the `storeprocedure` in one call and the sp returning a table with all the values evaluated. You can then use `DataTable` to go through the response. – Searching Nov 03 '16 at 02:20

2 Answers2

0
    string query = "SELECT * FROM table1;";

    query += "SELECT * FROM table2";

    using (SqlConnection con = new SqlConnection(constr))
    {
        using (SqlCommand cmd = new SqlCommand(query))
        {
            using (SqlDataAdapter sda = new SqlDataAdapter())
            {
                cmd.Connection = con;
                sda.SelectCommand = cmd;
                using (DataSet ds = new DataSet())
                {
                    sda.Fill(ds);                       
                }
            }
        }
    }
kritikaTalwar
  • 1,730
  • 1
  • 17
  • 25
0

I've recently seen that this question is still being viewed so I'll post the solution for anyone who is just starting off developing and encounters a similar challenge.

The most suitable solution was to create a stored procedure, pass each unique argument to it and return all the relevant data in a single response to the application. A custom model was defined for this output and the application logic adapted accordingly. The result is a longer running single call to the database as opposed to multiple individual ones.

Using the format from the question, the solution was:

C# code

static NewModel AllTotals(int arg1, int arg2)
{
    using (SqlConnection connection = new SqlConnection(connectionString))
    {
        connection.Open();
        var commandText = "TheStoredProcName";
        SqlCommand command = new SqlCommand(commandText, connection));
        command.CommandType = System.Data.CommandType.StoredProcedure;
        Cmd.Parameters.AddWithValue("@arg1", arg1);
        Cmd.Parameters.AddWithValue("@arg1", arg2);
        using (SqlDataReader dr = Cmd.ExecuteReader())
        {
            while (dr.Read())
            {
                var response = new NewModel(){
                    Value1 = Convert.ToDecimal(dr["value1"]),
                    Value2 = Convert.ToDecimal(dr["value2"]),
                };

                return(response);
            }
        }
    }

    return null;
}

SQL Stored Proc

CREATE PROCEDURE [dbo].[TheStoredProcName]
    @arg1 int,
    @arg2 int
AS
    DECLARE @value1 decimal(18,6) = ISNULL((--QUERY TO GET VALUE1),0)
    DECLARE @value2 decimal(18,6) = ISNULL((--QUERY TO GET VALUE2),0)
    
    -- select the variables into a result set for the application
    SELECT @value1 as [value1], @value2 as [value2]
Daniel
  • 2,167
  • 5
  • 23
  • 44