2012-03-28 174 views
1

我有一个应用程序,可以使用datetimepicker基于日期过滤datagridview。我的数据库中的“日期”列是日期时间数据类型,因此它将包含存储在其中的日期和时间,但有一些数据只有日期。我的问题是我的datetimepicker过滤器只能用date = 12:00:00 AM过滤这些数据。那些包含其他时间的数据在使用datatimepicker选择日期时无法过滤。我不知道有什么问题。这里是我的代码:可以过滤日期,但不能过滤日期时间?

public trackInput() 
    { 
     InitializeComponent(); 
     dataGridView1.Visible = false; 
     webBrowser1.Location = new Point(12, 141); 
    } 

    /*private void trackInput_Load(object sender, EventArgs e) 
    { 
     // TODO: This line of code loads data into the 'trackingBMSDATADataSet.BRDATA' table. You can move, or remove it, as needed. 
     this.bRDATATableAdapter.Fill(this.trackingBMSDATADataSet.BRDATA); 

    }*/ 
    private void trackBtn_Click(object sender, EventArgs e) 
    { 

     dataGridView1.Visible = true; 
     if (dataGridView1.Visible == true) 
     { 
      webBrowser1.Location = new Point(12, 397); 
     } 
     //DataTable dt = null; 
     string connoInput = textBox1.Text; 
     string conString = Properties.Settings.Default.BMSDATAConnectionString; 
     using (SqlCeConnection con = new SqlCeConnection(@"Data Source=C:\Documents and Settings\Administrator\My Documents\Visual Studio 2008\Projects\TrackCon\TrackCon\BMSDATA.sdf;Persist Security Info = True;Password=Gdex123$")) 
     { 

       string Ids = "conno= '" + System.Text.RegularExpressions.Regex.Replace(textBox1.Text.Trim(), @"\s*\n\s*", "' OR conno= '") + "'"; 
       SqlCeCommand com = new SqlCeCommand("SELECT conno,cmpsno,ctrx,dsysdate,cstnno,corigin FROM BRDATA WHERE " +Ids, con); 
       SqlCeDataAdapter adap = new SqlCeDataAdapter(com); 
       DataSet set = new DataSet(); 
       adap.Fill(set); 
       if (set.Tables.Count > 0) 
       { 
        bRDATABindingSource1.DataSource = set.Tables[0]; 
       } 
       bRDATABindingSource1.Filter = null; 
       dataGridView1.DataSource = bRDATABindingSource1; 
       con.Close(); 
     } 
    } 

    private void trackMPSbtn_Click(object sender, EventArgs e) 
    { 
     dataGridView1.Visible = true; 
     if (dataGridView1.Visible == true) 
     { 
      webBrowser1.Location = new Point(12, 397); 
     } 
     //DataTable dt = null; 
     //string connoInput = textBox1.Text; 
     string conString = Properties.Settings.Default.BMSDATAConnectionString; 
     using (SqlCeConnection con = new SqlCeConnection(@"Data Source=C:\Documents and Settings\Administrator\My Documents\Visual Studio 2008\Projects\TrackCon\TrackCon\BMSDATA.sdf;Persist Security Info = True;Password=Gdex123$")) 
     { 
      dataGridView1.DataSource = bRDATABindingSource1; 
      string Ids = "cmpsno= '" + System.Text.RegularExpressions.Regex.Replace(textBox2.Text.Trim(), @"\s*\n\s*", "' OR cmpsno= '") + "'"; 
      con.Open(); 
      SqlCeCommand com = new SqlCeCommand("SELECT conno,cmpsno,ctrx,dsysdate,cstnno,corigin FROM BRDATA WHERE " + Ids, con); 
      SqlCeDataAdapter adap = new SqlCeDataAdapter(com); 
      DataSet set = new DataSet(); 
      adap.Fill(set); 
      if (set.Tables.Count > 0) 
      { 
       bRDATABindingSource1.DataSource = set.Tables[0]; 
      } 
      bRDATABindingSource1.Filter = null; 
      dataGridView1.DataSource = bRDATABindingSource1; 
      con.Close(); 
     } 
    } 

    private void dateTimePicker1_ValueChanged(object sender, EventArgs e) 
    { 
     bRDATABindingSource1.Filter = string.Format("dsysdate = #{0:d/M/yyyy HH:mm tt}#", dateTimePicker1.Value.ToLongDateString()); 
    } 

回答

1

DateTimePicker具有包含选定日期的属性值。你应该使用这个日期,形成一个查询看起来像这样:

where somedate >= datetimepicker.Value.Date 
    and somedate < datetimepicker.Value.Date.AddDays(1) 

其中.Date只返回日期时间的日期部分。为了准备where子句中,替换其中具有

" where conno >= @startDate and conno < @endDate" 

SqlCeCommand的部分添加两个参数SqlCeCommand

com.Parameters.Add (new SqlCeParameter("@startDate", SqlDbType.DateTime, 
        textbox1.Value.Date)); 
com.Parameters.Add (new SqlCeParameter("@endDate", SqlDbType.DateTime, 
        textbox1.Value.Date.AddDays(1))); 

,做类似的活动与cmpsno。

更新:我完全错过了最后的方法。

private void dateTimePicker1_ValueChanged(object sender, EventArgs e) 
    { 
     bRDATABindingSource1.Filter = string.Format("dsysdate >= '{0:yyyy-MM-dd}' AND dsysdate < '{1:yyyy-MM-dd}'", dateTimePicker1.Value, dateTimePicker1.Value.AddDays(1)); 
    } 

在解释的努力:

由于dsysdate有你需要的过滤从午夜开始,并延伸至次日午夜的间隔时间组件 - 这是Value.AddDays(1)。不幸的是,我对Filter BindingSource的过滤知之甚少,因为我主要是在数据库级别进行过滤,因此我首先进行了过滤。您可能需要重写dateTimePicker1_ValueChanged以从数据库中检索数据,而不是在内存中进行筛选;当由于索引而使用较大的表格时,它会得到回报。说到这一点,你可能会考虑以不同的方式构建你的代码。这样的任务通常是通过一种方法来完成的,该方法检查过滤控件,构建查询并执行它,从而消除重复的代码并允许您一次过滤多个条件。方法比过滤控件的内容更改时被调用。

+0

对不起尼古拉,但我不太明白,你能解释一下吗? – 2012-03-28 02:07:41

+0

@ shahrul1509请参阅更新 – 2012-03-28 07:36:21

+0

感谢您的建议@尼古拉。 textboxt实际上是一个文本框。我的应用程序的总功能实际上是它有两个过滤器。一个是按ID过滤。用户可以输入ID,系统将显示ID信息。然后用户可以通过使用datetimepicker选择日期来进一步过滤该信息。我的问题在于日期过滤器。文本框过滤器工作正常。:) – 2012-03-28 07:40:19

0

我有几点意见:

1:串联文本永远不要编写查询。即使您尝试清理输入,也会受到SQL注入的影响。改为使用存储过程或参数化查询:它们完全免疫SQL注入。

第二:使用参数,因为您可以简单地传递原始形式的值,而不是将它们转换为文本。这将消除部分问题。您可以使用存储过程或参数化查询。

2nd & 1/2:还有其他原因使用参数,这与性能有关。

第3:可能按日期时间过滤将起作用,但您无法保证。您是否希望用户能够按照确切的日期时间进行过滤,包括秒和几分之一秒?我认为这不是一个好主意。请重新设计它或解释你想要做什么。它看起来没有多少意义。也许你应该在将日期存储在数据库之前将日期“舍入”到几秒或几分钟。你应该考虑日期时间不准确。它的工作原理有点像浮点数,所以你可以直接比较这些数值而不会有问题。也就是说,我等待您的意见来帮助您改进设计。

增加: 至于你说的部分时间并不重要,你可以插入删除,或在比较(在比较与参数datetime列),使用这个“绝招”:

SELECT (CAST(FLOOR(CAST(YourDateTimeColumn as FLOAT)) AS DateTime)) 

日期在内部存储为从基准日起的天数。小数部分表示一天中的小数部分(hh:mm:ss ...)。所以,如果你摆脱了小数,你只保留日期部分,并且可以安全地将它与给定日期进行比较。

如果您不需要时间部分:如果您使用的是SQL Server 2008或更高版本,则可以对列使用DATE类型(如果您不需要存储时间)。或者,您可以在将数据插入以前版本的SQL Server时使用相同的技巧。

+0

感谢提示。我会牢记并改进它。我在c#环境中仍然是新手,仍然在努力提高自己。对于第三条评论,当然用户不需要插入时间的确切细节。用户只需要选择一个日期,datagridview将根据选择的日期进行过滤。但正如我所说,在选择日期之后,过滤器只能检测到包含time = 12:00:00 AM的数据。那些含有其他时间的数据不能被检测到被过滤。 – 2012-03-28 01:35:51

+0

请看看如何摆脱datetime部分。还有其他一些方法,但我认为这是更快。 – JotaBe 2012-03-28 02:08:14

+0

对不起,理论上我理解它是如何工作的,但我不太清楚我需要放置哪些代码部分。我尽量把它放在这儿: '私人无效dateTimePicker1_ValueChanged(对象发件人,EventArgs的) {SqlCeCommand厘米= 新SqlCeCommand( “SELECT(CAST(FLOOR(CAST(dsysdate为FLOAT) 为DATETIME))FROM BRDATA” ); bRDATABindingSource1.Filter = 的String.Format ( “dsysdate =#{0:DD/MM/YYYY}#”,dateTimePicker1.Value.ToLongDateString());} ' 但是当我运行,所述 – 2012-03-28 02:23:54