here is the code, now I have 2 datetime pickers, set on Time (dtFrom, dtTo), I want them to get timestamp value for the selected type, and in format to include also milliseconds


namespace Project1
{
    public partial class Form1 : Form
    {
        public Form1() 
        {
            InitializeComponent();
            InitializeComboBox();
            numDataPointCount.ValueChanged += UpdateChartAndData;
            cmbSelection.SelectedIndexChanged += UpdateChartAndData;
        }
        public class AxisRange
        {
            public Types Type { get; }
            public int Min { get;}
            public int Max { get; }
            public AxisRange(Types type, int min, int max )
            {
                Type = type;
                Min = min;
                Max = max;
            }
        }
        public readonly List<AxisRange> yAxisRange = new List<AxisRange>()               //Min max value for each type , used for configuring the range of values in Y-axis
        {
            new AxisRange(Types.BOOL, 0, 1),
            new AxisRange(Types.BYTE, 0, 255),
            new AxisRange(Types.WORD, 0, 65535),
            new AxisRange(Types.DWORD, 0, int.MaxValue),
            new AxisRange(Types.LWORD, 0, int.MaxValue),
            new AxisRange(Types.SINT, -128, 127),
            new AxisRange(Types.USINT, 0, 255),
            new AxisRange(Types.INT, -32768, 32767),
            new AxisRange(Types.UINT, 0, 65535),
            new AxisRange(Types.DINT, int.MinValue, int.MaxValue),
            new AxisRange(Types.UDINT, 0, int.MaxValue),
            new AxisRange(Types.LINT, int.MinValue, int.MaxValue),
            new AxisRange(Types.ULINT, 0, int.MaxValue),
            new AxisRange(Types.REAL, -100000, 100000),
            new AxisRange(Types.LREAL, -100000, 100000),
            new AxisRange(Types.STRING, 0, 100),
            new AxisRange(Types.WSTRING, 0, 100),
            new AxisRange(Types.TIME, 0, 86400),
            new AxisRange(Types.LTIME, 0, int.MaxValue),
            new AxisRange(Types.DATE, 0, 365),
            new AxisRange(Types.DT, 0, 365),
            new AxisRange(Types.TOD, 0, 86400)
        };
        public string GetColumnName (Types type)    //Mapping (selecting and retrieving data from the database)
        {
            switch (type)
            {
                case Types.BOOL:
                case Types.BYTE:
                case Types.WORD:
                case Types.DWORD:
                case Types.SINT:
                case Types.USINT:
                case Types.INT:
                case Types.UINT:
                case Types.DINT:
                case Types.UDINT:
                case Types.TIME:
                case Types.DATE:
                case Types.DT:
                case Types.TOD:
                    return "int32";
                case Types.LWORD:
                case Types.LINT:
                case Types.ULINT:
                case Types.LTIME:
                    return "int64";
                case Types.REAL:
                    return "floating32";
                case Types.LREAL:
                    return "floating64";
                case Types.STRING:
                case Types.WSTRING:
                    return "stringType";
                default:
                   throw new ArgumentOutOfRangeException (nameof (type), $"No mapping found for {type}");
            }
        }
        private void InitializeComboBox()       //ComboBox adjustments
        {
            cmbSelection.Items.Add("Select Type");
            cmbSelection.Items.AddRange(Enum.GetNames (typeof (Types)));
            cmbSelection.SelectedIndex = 0;
        }
        private void UpdateChartAndData(object sender, EventArgs e)
        {
            if (cmbSelection.SelectedIndex > 0)
            {
                Types selectedType;
                if (Enum.TryParse(cmbSelection.SelectedItem.ToString(), out selectedType))
                {
                    int parameterID = (int)selectedType;
                    string columnName = GetColumnName(selectedType);

                    using (var context = new DataContext())
                    {
                        int totalRecordsCount = context.Reads.Count(r => r.ParameterID == parameterID);
                        numDataPointCount.Maximum = totalRecordsCount;

                        if (numDataPointCount.Value > totalRecordsCount)
                        {
                            MessageBox.Show($"The maximum data point limit of {totalRecordsCount}.");
                            return;
                        }

                        var firstRecord = context.Reads.Where(r => r.ParameterID == parameterID).OrderBy(r => r.TimeStamp).FirstOrDefault();
                        var lastRecord = context.Reads.Where(r => r.ParameterID == parameterID).OrderByDescending(r => r.TimeStamp).FirstOrDefault();

                        if (firstRecord != null && lastRecord != null)
                        {
                            dtFrom.Value = firstRecord.TimeStamp;
                            dtTo.Value = lastRecord.TimeStamp;
                        }
                    }

                    int dataPointLimit = (int)numDataPointCount.Value;
                    LoadData(parameterID, columnName, dataPointLimit);
                    LoadChart(parameterID, columnName, selectedType, dataPointLimit);
                }
            }
        }
        private void LoadData(int parameterID, string columnName, int dataPointLimit)    //DataGrid View loading data 
        {
            using (var context = new DataContext())
            {
                int totalRecordsCount = context.Reads.Count(r => r.ParameterID == parameterID);
                var records = (from r in context.Reads
                               where r.ParameterID == parameterID
                               orderby r.TimeStamp descending
                               select new
                               {
                                   r.ParameterID,
                                   r.TimeStamp,
                                   Value = EF.Property<object> (r, columnName)
                               })
                               .Take(dataPointLimit)
                               .OrderBy (r => r.TimeStamp)
                               .ToList();

                lblCount.Text = $"Total Count: {totalRecordsCount}";
                dgvShowTypeInfo.DataSource = records;
                dgvShowTypeInfo.Columns["TimeStamp"].DefaultCellStyle.Format = "yyyy-MM-dd HH:mm:ss.fff";
                dgvShowTypeInfo.Columns["TimeStamp"].Width = 150;

                UpdateStatistics(records.Select(r => r.Value));
            }
        }
        private void LoadChart(int parameterID, string columnName, Types selectedType, int dataPointLimit)   //Chart adjustments, visualizing it using ScottPlot
        {
            formsPlot1.Plot.Clear();
            var range = yAxisRange.FirstOrDefault(r => r.Type == selectedType);     //Min and max y-axis values for the selected type
            List<double> timestamps = new List<double>();                   //Lists X-axis(time), Y-axis(data value)
            List<double> values = new List<double>();

            using (var context = new DataContext())
            {
                var records = (from r in context.Reads             //Getting the records and converting them into a list of objects (timestamp and value)
                               where r.ParameterID == parameterID
                               orderby r.TimeStamp descending
                               select new
                               {
                                   r.TimeStamp,
                                   value = EF.Property<double>(r, columnName)
                               })
                            .Take(dataPointLimit)
                            .OrderBy (r => r.TimeStamp)
                            .ToList();
                if (records.Count > 0)
                {
                    foreach (var record in records)
                    {
                        timestamps.Add(record.TimeStamp.ToOADate());        //OADate format is used by ScottPlot for datetime to add to the list
                        values.Add(record.value);
                    }

                    if (range != null)
                    {                                                     //start padding and end padding, additional points are inserted
                        timestamps.Insert(0, timestamps.First());
                        values.Insert(0, range.Min);
                        timestamps.Add(timestamps.Last());
                        values.Add(range.Max);
                    }
                }
            }
            var scatter = formsPlot1.Plot.Add.Scatter(timestamps.ToArray(), values.ToArray());                 //Creating ScatterPlot 
            scatter.MarkerSize = 0;

            formsPlot1.Plot.XLabel("Time [OADate]");
            formsPlot1.Plot.YLabel("Values");
            formsPlot1.Plot.Axes.DateTimeTicksBottom();
            formsPlot1.Refresh();
        }
        private void UpdateStatistics (IEnumerable<object> values)   //Updating average, min max of values
        {
            var numericValues = values
                                  .Where(v => v != null && double.TryParse(v.ToString(), out _))
                                  .Select(v => Convert.ToDouble(v))
                                  .ToList();

            lblAverage.Text = $"Average: {(numericValues.Count > 0 ? numericValues.Average() : 0):F2}";
            lblMin.Text = $"Min: {(numericValues.Count > 0 ? numericValues.Min() : 0):F2}";
            lblMax.Text = $"Max: {(numericValues.Count > 0 ? numericValues.Max() : 0):F2}";
        }
    }
}