让这个ForEach更有效率

时间:2017-07-30 09:56:08

标签: c# sql asp.net

我有大约30-40辆车有个人呼号(4位数字),这将是弦乐。这些车辆中的每一辆都有自己的桌子。我需要检查这些表中的每一个并查看清理日期是否与传入的日期相同(使用" CleanDate"变量)当前我与以下ForEach循环打开连接如果日期= CleanDate

,则检查
  SqlConnection cnn = new SqlConnection(constr);
        cnn.Open();

        foreach (ListItem item in checkboxlistAM.Items)
        {
            string callsignstring = item.Text;
            string queryTable = "SELECT [date made ready AM] FROM [" + callsignstring + "]";
            SqlCommand cmd = new SqlCommand(queryTable, cnn);
            SqlDataReader rdr = cmd.ExecuteReader();

            while (rdr.Read())
            {
                if (rdr[0].ToString()!="")
                {
                    if ((DateTime)rdr[0] == CleanDate)
                    {
                        item.Selected = true;
                    }
                }
            }
            rdr.Close();


        }



        cnn.Close();

效率不高。我该如何做得更好?

我的想法是 -

SQL存储过程 - 任何人都可以帮助解决这个问题吗? 可以使用SP_MSFOREACHTABLE还是会降低效率?

添加"呼号" (字符串)到数组或列表并以某种方式传递它?

TIA

1 个答案:

答案 0 :(得分:4)

通常你不应该太担心性能,但是一旦你获得的不仅仅是checkboxlistAM.Items,那么在循环中进行数据库调用几乎总会变慢。

正如Kevin在评论中提到的那样,真正的问题是您正在使用相同的数据创建新表。

如果所有车辆具有相同的结构,您可以添加一个鉴别器列,该值将是您当前的表名。

或者,您可以使用UNION消除循环查询:

SELECT Id, PlateNumber, '1' AS Descriminator FROM Vehicles1
UNION
SELECT Id, PlateNumber, '2' FROM Vehicles2
UNION
SELECT Id, PlateNumber, '3' FROM etc

您可以使用View并仅从该视图中进行选择,而不是自己构建此查询:

SELECT * FROM VehiclesView WHERE Descriminator IN ('1', '2', ...);

为避免Sql注入,您可能不应自己构建SQL,而是使用ORM或SqlCommand.Parameters

如果您的数据对于每种类型的车辆都非常不同,可能仍会使用工会:

SELECT Id AS INTEGER1, PlateNumber AS STRING1, xxx AS STRING2 From Vehicles1
UNION
SELECT ID, yyy AS STRING1, zzz AS STRING2 FROM Vehicles2

这将是非常混乱但你可以实现某种AntiCorruption层,它将无法辨认的STRING1,STRING2 ......变回人类可读的东西。

如果所有车辆都如此不同,或许您可以使用NoSql数据库(如MongoDb)?

如果某些内容为IDisposable,请使用using构造。这是清理的好习惯:

using (SqlConnection cnn = new SqlConnection(constr))
{
  // do your stuff
  // .Close() will be called automatically
}