Click here to Skip to main content
15,885,366 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
hi all, i have winform visual studio 2012.
i hav a table "A" to which i want to fetch data in a specific way.

this is what i want to implement but i got unexpected result.
in fact when user opens the winform app on morning at 9 Am, i fetch from table A, data between day before night(10 pm) and current day 9Am. i save the last ID
Then after after each 2 hours, from the same table, i fetch data above last ID saved before (only data where id > previous id).
how can i do it?

actually my result is not what i want. i fetched always the same rows(data) from table A.i don't fetch rows where id > previous id

What I have tried:

int rnber = 0;
int rnber_last;
dchild = new DataTable();
string qrychild = "SELECT request_number,pincode,city WHERE request_number > '" + rnber + "' ;";

adap_child = new MySqlDataAdapter(qrychild, strcon);
adap_child.Fill(dchild);
rnber_last = Convert.ToInt32(dchild.AsEnumerable().Max(r => r["request_number"]));
rnber = rnber_last;
Posted
Updated 29-May-16 4:37am
v2
Comments
George Jonsson 28-May-16 4:42am    
So what is the problem?
You have described what you are doing, but not if you get any errors or if you get an unexpected result.
Armel_Djient 28-May-16 4:50am    
i got unexpected result. what i have done, i ping the database every time and that makes the app slow. let me improve my question
George Jonsson 28-May-16 5:04am    
Always use the Reply button if you want to make sure to notify the person are replying to.

So what is the unexpected result and what is the result you expect.
And where in the code does it happen.

You do realize that we cannot see your screen, read your hard disk or read your mind.
We cannot test run your code either without setting up a system similar to yours, so provide as much relevant information as you can.
Peter Leow 28-May-16 6:53am    
Consider using a datetime field to do the job.

1 solution

As @PeterLeow has pointed out, this would be a lot easier if you had a datetime column. As things have been described I can see no way of identifying the data that has been loaded after 10pm the previous day.

So the solution I'm offering here is focussing on the request_number in a similar way to the code snippet you posted.

Here is the full code
C#
using System;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Windows.Forms;

namespace Sandbox
{
    public partial class Sandbox : Form
    {
        readonly string connectionString = ConfigurationManager.ConnectionStrings["ConnectToDB"].ConnectionString;
        private const string Qrychild = "SELECT request_number,pincode,city FROM testtable WHERE request_number > @no;";
        private int rnberLast;
        private const string LastNumber = "lastNumber";
        private DataTable dchild;
        public Sandbox()
        {
            InitializeComponent();
        }
        private void Sandbox_Load(object sender, EventArgs e)
        {
            //Initial data load
            rnberLast = GetDataSinceLastId(LastIdFromConfig());
            WriteSetting(LastNumber, rnberLast.ToString());

            //Initialise the timer
            timerCheckDB.Interval = (2*60*60*1000); //2 hours
            timerCheckDB.Enabled = true;
        }

        private int LastIdFromConfig()
        {
            try
            {
                var s = ReadSetting(LastNumber);
                if (!int.TryParse(s, out rnberLast))
                    rnberLast = 0;
            }
            catch (Exception)
            {
                rnberLast = 0;
            }
            return rnberLast;
        }
        static string ReadSetting(string key)
        {
            var configFile = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            var settings = configFile.AppSettings.Settings;
            return settings[key] != null ? settings[key].Value : "";

        }
        static void WriteSetting(string key, string value)
        {
            var configFile = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            var settings = configFile.AppSettings.Settings;
            if (settings[key] == null)
                settings.Add(key, value);
            else
                settings[key].Value = value;

            configFile.Save(ConfigurationSaveMode.Modified);
            ConfigurationManager.RefreshSection(configFile.AppSettings.SectionInformation.Name);
        }

        private int GetDataSinceLastId(int lastId)
        {
            using (var cnn = new SqlConnection(connectionString))
            {
                using (var adapChild = new SqlDataAdapter(Qrychild, cnn))
                {
                    dchild = new DataTable();
                    adapChild.SelectCommand.Parameters.AddWithValue("@no", lastId);
                    adapChild.Fill(dchild);
                    //dataGridView1.DataSource = dchild; //visual debugging aid
                    return dchild.Rows.Count > 0 ? int.Parse(dchild.AsEnumerable().Max(r => r["request_number"]).ToString()) : lastId;
                }
            }
        }

        private void timerCheckDB_Tick(object sender, EventArgs e)
        {
            rnberLast = GetDataSinceLastId(rnberLast);
            WriteSetting(LastNumber, rnberLast.ToString());
        }
    }
}

Explanation:

The method GetDataSinceLastId takes the number of the lastId saved and retrieves all data rows where the request_number is greater than that number. Note the differences between your code and mine: I've used a parameterised query and I'm using int.Parse instead of Convert.ToInt

The method LastIdFromConfig reads the application configuration file to get the last request_number that was read from the database on the previous run. As soon as the new data (if any) has been loaded, then the WriteSetting method updates the config file with the new last id (request_number)

An initial data load happens as soon as the form is loaded and the timer is initialise and enabled. The timerCheckDB_Tick subsequently attempts to reload the data at the given interval.

The key to getting this to work is persisting the last request_number - here is my App.Config file
XML
<configuration>
    <startup> 
        <supportedruntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
  <connectionstrings>
    <add name="ConnectToDB">
        connectionString="Data Source=MyDataSource;Initial Catalog=Sandbox14;Integrated Security=True"
        providerName="System.Data.SqlClient" />
  </add></connectionstrings>
  <appsettings>
    <add key="lastNumber" value="5" />
  </appsettings>
</configuration>
(Note the config file is overwritten in the bin\debug folder everytime you run in debug mode. To prevent this go to the Project, Properties, Debug tab and untick the "Enable the Visual Studio hosting process" checkbox)
In this case I've used the App.config to persist the data. A better option is to have this as a User Setting
Using Application Settings and User Settings[^]
User Settings Applied[^]
Windows Forms User Settings in C#[^]

This does not fit your requirement as stated
Quote:
in fact when user opens the winform app on morning at 9 Am, i fetch from table A, data between day before night(10 pm) and current day 9Am. i save the last ID
This version will always retrieve data loaded after the previous id. To be able to handle time in this way you will need a DateTime column on your table and you will probably want to persist the DateTimeLastRun in the settings.

[EDIT]
My apologies - I forgot to mention that you will need to change SqlConnection and SqlDataAdapter to MySqlConnection and MySqlDataAdapter in the code above
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900