Home > Software design >  How to avoid writing same code for different types
How to avoid writing same code for different types

Time:07-31

I'm writing a C# program with SQL Server and SQL Server CE. How can I avoid writing same code like below, variable databasestate is used to see if program should use SQL Server or SQL Server CE.

public static void Delete()
{
    SqlCeCommand commce = new SqlCeCommand("Delete From Projekat WHERE IDProjekat = @ConID", conce);

    SqlCommand comm = new SqlCommand("Delete From Projekat WHERE IDProjekat = @ConID", con);

    if (CrossFormData.databasestate == false)
    {
        commce.Parameters.AddWithValue("@ConID", CrossFormData.ProjectID);

        try
        {
            conce.Open();
            commce.ExecuteNonQuery();
            conce.Close();

            MessageBox.Show("Deleted!");
        }
        catch (Exception)
        {
            MessageBox.Show("Something went wrong");
            conce.Close();
        }
    }
    else
    {
        comm.Parameters.AddWithValue("@ConID", CrossFormData.ProjectID);

        try
        {
            con.Open();
            comm.ExecuteNonQuery();
            con.Close();

            MessageBox.Show("Deleted!");
        }
        catch (Exception)
        {
            MessageBox.Show("Something went wrong");
            con.Close();
        }
    }
}

If using SQL Server CE is making you angry, I'm sorry next time I will use SQLite.

If I don't find a way I will separate them in two different classes so it's more organized.

CodePudding user response:

Both SqlCeCommand and SqlCommand derive from DbCommand, so program against the base class:

var connection = CrossFormData.databasestate ? (DbConnection) con : conce;
using var command = connection.CreateCommand();
command.CommandText = "Delete From Projekat WHERE IDProjekat = @ConID";
command.Parameters.AddWithValue("@ConID", CrossFormData.ProjectID);

try
{
    connection.Open();
    command.ExecuteNonQuery();
    MessageBox.Show("Deleted!");
}
catch (DbException)
{
    MessageBox.Show("Something went wrong");
}
finally
{
    connection.Close();
}

Even better, use a helper library such as Dapper to eliminate a lot of this boilerplate:

var connection = CrossFormData.databasestate ? (DbConnection) con : conce;
connection.Execute("Delete From Projekat WHERE IDProjekat = @ConID", new { ConID = CrossFormData.ProjectID });

CodePudding user response:

I fail to see how separating into two classes solves the issue of duplicate code, but here's a starting point: SqlCeCommand and SqlCommand both derive from DbCommand, so if you could rewrite the code maybe with an input parameter of the command (as a DbCommand) is should work regardless of which case it is. Additionally, from what I gather con and conce should either be the same class or share a parent class, so that hopefully shouldn't be an issue. I looked up the methods used as well, and they all come from DbCommand. Best of luck, and let me know if you need more info (or I can write some code to show you what I mean, I'm just at dinner right now lol).

  • Related