优化C#代码/硬编码

时间:2016-04-13 23:48:12

标签: c# asp.net drop-down-menu

首先,我想提一下我不是编码员。基本上,我从头开始学习C#,我真的不介意。

以下是我的代码试图完成的一些背景知识。

我有一个用于数据库名称的级联DDL1。当用户选择数据库名称时,他们需要为日期范围选择DDL2(使用“some”参数运行不同的查询)。

它运行的查询涉及连接来自不同数据库的2个表(我认为这是我遇到的整体问题)。

我可以让代码工作,但它看起来真的很乏味,我确信硬编码是不受欢迎的,除非必要。我做了一些研究,看起来我需要使用动态SQL来参数化存储过程中的数据库名称,我不想使用它。

总而言之。对于每个数据库名称和每个日期范围,我需要单独对它们进行硬编码。这将是每个数据库总共4个代码块。如果数据全部存在于1个表中,我就不会有这个问题。

同样,我是一个相当新的,几乎是初学者。请告诉我是否有可能优化代码并使其更有效,因为截至目前,它对我来说看起来很糟糕。

下面提供了代码,谢谢:

protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{

{
    DataTable dt = new DataTable();
    SqlDataAdapter Adpt;

    if (DropDownList1.SelectedValue == string.Empty & DropDownList2.SelectedValue == string.Empty)
    {
    }

    if (DropDownList1.SelectedItem.Text == "ytd" & DropDownList2.SelectedValue == "db1")
        using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["db1ConnectionString"].ConnectionString))
        {
            SqlCommand cmd = new SqlCommand("select sum(column1) from table1 inner join db2.dbo.table2 on db2.dbo.table2.ID = db1.dbo.table3.id where somecolumn = @somecolumn and Date <= GetDate() AND YEAR(Date) = year(GetDate()) AND Status = @Status", con);
            cmd.Parameters.AddWithValue("@somecolumn", DropDownList2.SelectedValue);
            cmd.Parameters.AddWithValue("@status", "done");
            Adpt = new SqlDataAdapter(cmd);
            new SqlDataAdapter(cmd).Fill(dt);
        }

    if (DropDownList1.SelectedItem.Text == "yesterday" & DropDownList2.SelectedValue == "db1")
        using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["db1ConnectionString"].ConnectionString))
        {
            SqlCommand cmd = new SqlCommand("select sum(column1) from table1 inner join db2.dbo.table2 on db2.dbo.table2.ID = db1.dbo.table3.id where somecolumn = @somecolumn and Date >= DATEADD(DAY, DATEDIFF(DAY, 1, GETDATE()), 0) AND Date <= DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()), 0) AND Status = @Status", con);
            cmd.Parameters.AddWithValue("@somecolumn", DropDownList2.SelectedValue);
            cmd.Parameters.AddWithValue("@status", "done");
            Adpt = new SqlDataAdapter(cmd);
            new SqlDataAdapter(cmd).Fill(dt);

    //if same code, different database
        {
        }

    //if same code, different database
        {
        }

    //else if same code, different database           
        {
        }

    GridView1.DataSource = dt;
    GridView1.DataBind();

}


protected void DropDownList2_SelectedIndexChanged(object sender, EventArgs e)
{
    {
        if (DropDownList2.SelectedIndex == 0)
        {
            DropDownList1.SelectedIndex = 0;
            DropDownList1.Enabled = false;
        }
        else
        {
            DropDownList1.Enabled = true;
            DropDownList1.SelectedIndex = 0;
        }

    }
}

}

1 个答案:

答案 0 :(得分:1)

良好编程的关键是尽可能消除冗余。如果您的大部分代码都相同或非常相似,请说明如何不重复自己。

例如,对代码的快速重构看起来像这样:

SELECT
    a2.name AS [tablename],
    a1.rows as row_count,
    (a1.reserved + ISNULL(a4.reserved,0))* 8 AS reserved, 
    a1.data * 8 AS data,
    (CASE WHEN (a1.used + ISNULL(a4.used,0)) > a1.data THEN (a1.used + ISNULL(a4.used,0)) - a1.data ELSE 0 END) * 8 AS index_size,
    (CASE WHEN (a1.reserved + ISNULL(a4.reserved,0)) > a1.used THEN (a1.reserved + ISNULL(a4.reserved,0)) - a1.used ELSE 0 END) * 8 AS unused
FROM
    (SELECT 
        ps.object_id,
        SUM (
            CASE
                WHEN (ps.index_id < 2) THEN row_count
                ELSE 0
            END
            ) AS [rows],
        SUM (ps.reserved_page_count) AS reserved,
        SUM (
            CASE
                WHEN (ps.index_id < 2) THEN (ps.in_row_data_page_count + ps.lob_used_page_count + ps.row_overflow_used_page_count)
                ELSE (ps.lob_used_page_count + ps.row_overflow_used_page_count)
            END
            ) AS data,
        SUM (ps.used_page_count) AS used
    FROM sys.dm_db_partition_stats ps
        WHERE ps.object_id NOT IN (SELECT object_id FROM sys.tables WHERE is_memory_optimized = 1)
    GROUP BY ps.object_id) AS a1
LEFT OUTER JOIN 
    (SELECT 
        it.parent_id,
        SUM(ps.reserved_page_count) AS reserved,
        SUM(ps.used_page_count) AS used
     FROM sys.dm_db_partition_stats ps
     INNER JOIN sys.internal_tables it ON (it.object_id = ps.object_id)
     WHERE it.internal_type IN (202,204)
     GROUP BY it.parent_id) AS a4 ON (a4.parent_id = a1.object_id)
INNER JOIN sys.all_objects a2  ON ( a1.object_id = a2.object_id ) 
INNER JOIN sys.schemas a3 ON (a2.schema_id = a3.schema_id)
WHERE a2.type <> N'S' and a2.type <> N'IT'
ORDER BY a3.name, a2.name

但仍有更大的改进空间。您可以重新组织whereClause,以便状态仅出现在一个位置。您还应该考虑使用switch语句而不是if语句的大块。

至于硬编码。完成的状态有点奇怪。如果它将完成&#39;总是只做一部分select语句而不是param。像你一样编写内联sql并不一定是坏事。您对查询进行了参数化,以避免SQL注入攻击,这很好。

修改: 更改数据库的一种方法是使用String.Format,它将用该索引的变量替换{#}标记。

var selectStatement = "select sum(column1) from table1 inner join db2.dbo.table2 on db2.dbo.table2.ID = db1.dbo.table3.id where somecolumn = @somecolumn "
string whereClause;

if (DropDownList2.SelectedValue == "db1")
{
    if (DropDownList1.SelectedItem.Text == "ytd")
    {
        whereClause = "and Date <= GetDate() AND YEAR(Date) = year(GetDate()) AND Status = @Status";
    }
    else if (DropDownList1.SelectedItem.Text == "yesterday")
    {
        whereClause = "and Date >= DATEADD(DAY, DATEDIFF(DAY, 1, GETDATE()), 0) AND Date <= DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()), 0) AND Status = @Status"
    }
}

//etc

SqlCommand cmd = new SqlCommand(selectStatement + whereClause, con);
cmd.Parameters.AddWithValue("@somecolumn", DropDownList2.SelectedValue);
cmd.Parameters.AddWithValue("@status", "done");
Adpt = new SqlDataAdapter(cmd);
new SqlDataAdapter(cmd).Fill(dt);

GridView1.DataSource = dt;
GridView1.DataBind();

再次查看代码,您可能需要在if块中移动分配这些db变量,并将selectStatement声明移到最后。