首先,我想提一下我不是编码员。基本上,我从头开始学习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;
}
}
}
}
答案 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声明移到最后。