使用C#中的TimeSpan简化if else条件语句

6

我需要创建一个实时报告。为此,我必须为给定日期的每个小时编写条件。在下面的代码中,条件检查当前星期几,然后检查当前时间,并根据此生成报告。

protected void sample()
{
    TimeSpan zerothHour = new TimeSpan(00, 0, 0);
    TimeSpan firstHour = new TimeSpan(01, 0, 0);
    TimeSpan secondHour = new TimeSpan(02, 0, 0);
    TimeSpan thirdHour = new TimeSpan(03, 0, 0);
    TimeSpan fourthHour = new TimeSpan(04, 0, 0);
    TimeSpan fifthHour = new TimeSpan(05, 0, 0);
    TimeSpan sixthHour = new TimeSpan(06, 0, 0); 
    // and so on until the twentyfourth hour
    if (DateTime.Today.DayOfWeek == DayOfWeek.Monday)
    {
        if (DateTime.Now.TimeOfDay >= sixthHour && DateTime.Now.TimeOfDay <= seventhHour)
        {
            //MySql query here
            string MyConString = ConfigurationManager.ConnectionStrings["connStr"].ConnectionString;
            MySqlConnection connection = new MySqlConnection(MyConString);
            string agentlogin = "SELECT agentlogin FROM agentdetails WHERE location = 'PNQ10-Pune' AND shift IN('6:00-15-00', '22:00-7:00') AND Mon = 'W'";
            MySqlCommand cmd = new MySqlCommand(agentlogin, connection);
            connection.Open();
            MySqlDataReader rdr = cmd.ExecuteReader();
            while (rdr.Read())
            {
               //lblagentlogin.Text += rdr["agentlogin"] + Environment.NewLine;
                sqlList.Add(Convert.ToString(rdr["agentlogin"]));
            }
        }
        else if(DateTime.Now.TimeOfDay >= seventhHour && DateTime.Now.TimeOfDay <= eigthHour)
        {

        }
        else if (DateTime.Now.TimeOfDay >= eigthHour && DateTime.Now.TimeOfDay <= ninthHour)
        {

        }
        else if (DateTime.Now.TimeOfDay >= ninthHour && DateTime.Now.TimeOfDay <= tenthHour)
        {

        }
        else if (DateTime.Now.TimeOfDay >= tenthHour && DateTime.Now.TimeOfDay <= eleventhHour)
        {

        }
        // and so on for the entire cycle of time
    }
}

上面的代码仅适用于星期一,我还需要为其他七天做同样的事情。如果我在每个条件中添加查询,代码将变成数百行。

有没有更好的方法,在不必编写数百行代码的情况下完成此操作?


1
for循环怎么样?或者使用Quartz进行任务调度呢? - ProgrammingLlama
1
OT DateTime.Today.TimeOfDay <= seventhHour,你应该使用 < 而不是 <= - Hans Kesting
1
你确定这是正确的方法吗?根据小时,你的MySQL查询有什么不同? - Jonas Høgh
你应该尝试一下 @Enigmativity 的答案。 - kgzdev
1
@Enigmativity 好的,我已经撤销了更改。谢谢你告诉我 :) - prkash
显示剩余12条评论
3个回答

10

这对你有效吗?

var sqls = new []
{
    "select x from y",
    "select w from q",
    // etc - 24 options
};

var sql = sqls[DateTime.Now.Hour];

或者甚至更好:

var sqls = new Action[]
{
    () => { /* sql for midnight */ },
    () => { /* sql for 1 am */ },
    // etc
    () => { /* sql for 11 pm */ },
};

var sql = sqls[DateTime.Now.Hour];

sql.Invoke();
如果你需要获取“星期几”和“小时”的话,可以使用以下代码:DayOfWeekHour
var sqls = new string[][]
{
    new [] { "select x from y", "select w from q", },
    new [] { "select x from y", "select w from q", },
    new [] { "select x from y", "select w from q", },
    new [] { "select x from y", "select w from q", },
    new [] { "select x from y", "select w from q", },
    new [] { "select x from y", "select w from q", },
    new [] { "select x from y", "select w from q", },
};

var sql = sqls[(int)DateTime.Now.DayOfWeek][DateTime.Now.Hour];
根据评论和其他答案,以下是更简洁的方法:
string day = DateTime.Now.DayOfWeek.ToString().Substring(0, 3);

string[] shifts = new []
{
    "('22:00-7:00')",
    "('22:00-7:00', '6:00-15:00')",
    // 24
};

string shift = shifts[DateTime.Now.Hour];

string sql = $"SELECT agentlogin FROM agentdetails WHERE location = 'PNQ10-Pune' AND shift IN {shifts} AND {day} = 'W'";

不错的方法。如果我们将数组变为二维的,可以表示天和小时。 - kgzdev
当然可以使用不规则数组。 - Enigmativity
@prkash - 如果您能提供一些您正在尝试编写的代码示例,以便在每个if部分内实际编写代码,那么编写所需的代码将变得更加容易。这似乎是一个相当简单的重构练习。 - Enigmativity
当然,我正在更新我现在尝试的内容。将在问题上进行编辑。 - prkash
@prkash - 为什么要选择更复杂的switch选项,Jonas提出了这个。我的数组方法做同样的事情,但更简单。 - Enigmativity
显示剩余4条评论

2

从您的情况看,通过动态生成SQL可以大大简化您的代码。我猜测一下,因为我不完全了解您的数据模型,但是以下内容可能会有所帮助:

var dayColumns = new [] { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
var currentDayColumn = dayColumns[(int) DateTime.Now.DayOfWeek];

string shifts;

switch (DateTime.Now.Hour) {
  case 0:
    shifts = "('22:00-7:00')"
    break;
  case 6:
    shifts = "('22:00-7:00', '6:00-15:00')"
    break;
  //TODO - more cases
}

string sql = "SELECT agentlogin FROM agentdetails WHERE location = 'PNQ10-Pune' AND shift IN " + shifts + " AND " + currentDayColumn + " = 'W'";

如果您可以将班次更改为两列,并显示开始和结束时间,那么可以进一步优化如下:
var hour = DateTime.Now.Hour

string sql = "SELECT agentlogin FROM agentdetails WHERE location = 'PNQ10-Pune' AND " + hour + " >= shift_start_hour AND " + hour + " < shift_end_hour AND " + currentDayColumn + " = 'W'";

我认为这将解决星期几部分的问题,但是我的表中有超过10种类型的班次。我是否需要在switch内创建情况的组合? - prkash
可以这样做。但是,如果您可以更改数据模型,也许它也需要重新设计。是否有可能将班次列更改为两个整数列,表示班次开始和结束的小时数? - Jonas Høgh
我认为使用你的方法和我的方法一起会非常有效。 - prkash
请检查您的方法所做的最新编辑。它确实有效,但我必须为每个小时编写条件,这没关系,但如果有更好的方法,我想知道。我无法更改该列,我对此没有控制权。 - prkash
1
不要硬编码所有的小时/班次组合,您可以添加另一个表格,列出按小时计算的所有适用班次。然后基于传递的小时参数在该表格上进行连接。 - Hans Kesting
@HansKesting 是的,那会起作用,我会这样做。谢谢 :) - prkash

1
假设你的 SQL 查询也依赖于星期几和小时数(否则就没有太多意义了),你可以这样处理:
protected void sample()
{
    var now = DateTime.Now;
    var sql = GetSql(now.DayOfWeek, now.Hour);
    // execute sql
}

protected string GetSql(DayOfWeek dayofweek, int hour)
{
    // generate sql, using "(int)dayofweek" if needed
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接