Stuck in loading data from database - c#

In making this appointment calendar, I wanted to use access database to save and retrieve my appointments. However I have more than one property type (Strings, Ints, DateTime) and more than one type of boxes (ComboBox, ListBox, DateTimePicker) to display in the windows forms.
I have managed to write my code for the database with the following code (part of it):
foreach(var appointment in listOfAppointments)
{
OleDbCommand DbCommand = new OleDbCommand(
"INSERT INTO NewAppointmentDatabase " +
"([Start], [Length], [DisplayableDescription], [OccursOnDate], [Location], [IsRecurring], [Frequency], [Occurence]) " +
"VALUES(#Start, #Length, #DisplayableDescription, #OccursOnDate, #Location, #IsRecurring, #Frequency, #Occurence)",
SaveAppntAccess);
DbCommand.Connection = SaveAppntAccess;
DbCommand.Parameters.AddWithValue("#Start", appointment.Start); //is a short time in DateTime
DbCommand.Parameters.AddWithValue("#Length", appointment.Length); //is an int
DbCommand.Parameters.AddWithValue("#DisplayableDescription", appointment.DisplayableDescription); //is a long string
DbCommand.Parameters.AddWithValue("#OccursOnDate", appointment.OccursOnDate(date)); //is a boolean with DateTime as argument
DbCommand.Parameters.AddWithValue("#Location", appointment.Location); //is a string
DbCommand.Parameters.AddWithValue("#IsRecurring", appointment.IsRecurring); //is a boolean with yes/no tickbox
DbCommand.Parameters.AddWithValue("#Frequency", appointment.Frequency); //is a string
DbCommand.Parameters.AddWithValue("#Occurence", appointment.Occurence); //is an int
I have to note that the word date in appointment.OccursOnDate(date) is reddened in visual studio which is kind of weird because the boolean parameter is inherited.
And then comes the tricky part: I want to load my data! But I want to take my values from the database and assign them to each property first, and then take those and display them in the ComboBoxes and TextBoxes and DateTimePickers.
The code goes like this (part of it):
if(LoadAppntAccess.State == ConnectionState.Open)
{
OleDbCommand DbCommand = new OleDbCommand(
"SELECT * FROM NewAppointmentDatabase", LoadAppntAccess);
OleDbDataReader reader = null;
DbCommand.Connection = LoadAppntAccess;
reader = DbCommand.ExecuteReader();
foreach (var appointment in listofAppointments)
{
while (reader.Read())
{
//code to complete
}
}
}
How will I assign the values from each field to each property? I was thinking something like this:
appointment.Start.Add(reader["Start"].ToString());
appointment.Length.Add((reader["Length"].ToString());
appointment.DisplayableDescription(reader["DisplayableDescritpion"].ToString());
But I get errors in all of those - what is the right syntax?
EDIT : I forgot to mention that "start" although it's assigned as DateTime, I used as a ShortTime value because I wanted a ComboBox with time and 30 minute intervals. So it's not exactly a Date. For OccursOnDate it was written as:
public bool OccursOnDate(DateTime date)
{
return date.Date == date;
}
and to retrieve a date I used a DateTimePicker.
2nd edit for more info
My class looks like this:
public class Appointment : IAppointment
{
public DateTime Start { get; set; }
public int Length { get; set; }
public string DisplayableDescription { get; set; }
public bool OccursOnDate(DateTime date)
{
return date.Date == date;
}
//custom members
public int ID { get; }
public string Location { get; set; }
public bool IsRecurring { get; set; }
public string Frequency { get; set; }
public int Occurence { get; set; }
public Appointment()
{
}
but unfortunately it inherits the parameters from IAppointment which has this code.
int ID { get; }
DateTime Start { get; }
int Length { get; }
string DisplayableDescription { get; }
bool OccursOnDate(DateTime date);
//custom members
string Location { get; set; }
bool IsRecurring { get; set; }
string Frequency { get; set; }
int Occurence { get; set; }
The custom members are my addition since I had to put some extra stuff according to the specs.
However I managed to find a syntax based on your answers below.
appointment.Start.((DateTime)reader["Start"]);
appointment.Length.((int)reader["Length"]);
appointment.DisplayableDescription.((string)reader["DisplayableDescritpion"]);
appointment.OccursOnDate((DateTime)reader["OccursOnDate"]);
appointment.Location.((string)reader["Location"]);
appointment.IsRecurring.((bool)reader["IsRecurring"]);
appointment.Frequency.((string)reader["Frequency"]);
appointment.Occurence.((int)reader["Occurence"]);
I still get this message:
Any clues?

From the info you have given i would guess something like this:
appointment.Start = (DateTime)reader["Start"];
appointment.Length = (int)reader["Length"];
appointment.DisplayableDescription = (string)reader["DisplayableDescritpion"];
This is just a simple example, we would need more info to give a better answer. If any of the columns can have a null value you need to handle that as well etc..

access reader's columns like this, using column index (column index 0 is first column from your SELECT clause, 1 is second... etc). As you can see, call reader's right method to get appropriate type of data.
appointment.Start = reader.GetDateTime(0);
appointment.Length = reader.GetInt32(1);
appointment.DisplayableDescription= reader.GetString(2);
you can also get data by specifiying column name.
appointment.Start = reader.GetDateTime(reader.GetOrdinal("Start"));
appointment.Length = reader.GetInt32(reader.GetOrdinal("Length"));
appointment.DisplayableDescription = reader.GetString(reader.GetOrdinal("DisplayableDescritpion"));

I posted in a comment but since it wasn't made clear with no picture I am posting now my previous try that didn't work and explain.
This is the code mentioned both by #Nino and #FsDaniel
If you see the Interface's parameters (in my initial post), they only have the get property which makes Start, Length and DisplaybleDescritption readonly. Thus the error. The rest is ok because they are my custom members and I gave them get and set properties. I do not wish to make any alterations in the Interface, that's why I am asking to find if there can be another solution.

Related

Get property value of object in an list

I want to get an property value from an object that is in a list and put it into textbox.text
Below i have an example of my code:
The object:
public class Incident
{
public int Incident_id { get; set; }
public string Description { get; set; }
public string Caller { get; set; }
}
Below is my code in my form class:
List<Incident> incidentById = new List<Incident>();
incidentById = db.GetIncidentById(ID);
when my list is filled i want to put the string Caller into an textbox somewhat like below:
textBoxCaller.Text = incidentById[1].Caller;
I'm stuck at this point so i hope someone can help me out.
Thanks!
EDIT:
public List<Incident> GetIncidentById(int id)
{
using (IDbConnection connection = new System.Data.SqlClient.SqlConnection(Helper.CnnVal("IncidentLog")))
{
var output = connection.Query<Incident> ($"select * from Incidents where Incident_id like #id", new { id = "%id%" }).ToList();
return output;
}
}
I wasn't passing the right value into my query
this did the trick!
What you want is $"select * from Incidents where Incident_id = #id", new { id }
do you want first value should go?
check like.
if(incidentById.Count>0)
{
textBoxCaller.Text = incidentById.First().Caller;
}
// or you can join all Caller in list like
if(incidentById.Count>0)
{
textBoxCaller.Text = string.join(",",incidentById.Select(x=>x.Caller));
}
The issue that you are facing is that you are trying to access the second element in the list when there are not two or more elements in the list. If you are trying to access the first element in the list, then you could do either
textBoxCaller.Text = incidentById[0].Caller;
or
textBoxCaller.Text = incidentById.First().Caller;
If you do in fact want the second element of the list, then you should be checking to verify that it's length is at least two:
if(incidentById.Count >= 2)
{
...
}
Finally, as mentioned in a comment, you should rename GetIncidentById to something that makes clear it is returning a list, like GetIncidentsById or something similar.

Moving app.config settings to db and using value type to dynamically set the return data type

I have a windows service application that I want to manage setting for from a asp.net site. As my application has grown, my list of settings in the app.config file has grown as well. So, I have decided to move these setting to a table in my SQLDB to be able to track them and give me a way to modify the settings from the admin site. I ran into an issue where I am trying to store the setting value type in the table and then use it to change the value property to the type stored. For instance I have quite a few TimeSpan defined. In the SQL table the data would look like this.
guid settingName settingValue settingType
936767f5-63b5-4844-9991-29f6f92c53f2 SMTimeStart 12:00:00 TimeSpan
Im trying to use the following code to pull the settings and return it in the correct type.
public class SettingDataValue
{
public Guid guid { get; set; }
public string SettingName { get; set; }
public string SettingValue { get; set; }
public string SettingType { get; set; }
}
public static dynamic getSettingFromDB(string name)
{
SettingDataValue s = new SettingDataValue();
using (IDbConnection _db = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString), commandTimeout = null)
{
s = _db.Query<SettingDataValue>("Select Guid, SettingName, SettingValue ,SettingType from SiteSettings where settingName = '" + name + "'").SingleOrDefault();
}
PropertyInfo propertyInfo = s.GetType().GetProperty(s.SettingType);
propertyInfo.SetValue(s, Convert.ChangeType(s.SettingValue, propertyInfo.PropertyType), null);
return s.SettingValue;
}
However when I run this I get a null reference exception on the
propertyInfo.SetValue(s, Convert.ChangeType(s.SettingValue, propertyInfo.PropertyType), null);
I know the query works when I test it and watch it with the sql profiler. Any thoughts or suggestions?
So couple things I had wrong. As David mentioned, I didnt need to use reflection to get the type. Instead I needed to use the Type.GetType method to parse the text. Also the second thing was that the data types have to be the namespace recorded with them.
Here is the updated code that is working now.
public class SettingDataValue
{
public Guid guid { get; set; }
public string SettingName { get; set; }
public string SettingValue { get; set; }
public string SettingType { get; set; }
}
public static dynamic getSettingFromDB(string name)
{
SettingDataValue s = new SettingDataValue();
using (IDbConnection _db = new SqlConnection(ConfigurationManager.ConnectionStrings["NetworkCafeConnectionString"].ConnectionString))
{
s = _db.Query<SettingDataValue>("Select guid, SettingName, SettingValue ,SettingType from SiteSettings where SettingName = '" + name + "'").FirstOrDefault();
}
Type type = Type.GetType(s.SettingType);
var converter = TypeDescriptor.GetConverter(type);
return converter.ConvertFrom(s.SettingValue);
}
Here is a sample of the data in the sql table.
guid SettingName SettingValue SettingType
95473a84 SMCreateTime 00:12:00 System.TimeSpan
81037bdc SMCreateEnabled True System.Boolean
99e06df7 SMUsername Username System.String
The problem you're having isn't that you aren't getting data back, but that the PropertyInfo is null.
The line:
PropertyInfo propertyInfo = s.GetType().GetProperty(s.SettingType);
Is actually trying to find the property "TimeSpan" on the SettingDataValue object (using the line of data you provided). Since this property does not exist it is returning null. Then you're trying to set the value of the property and getting the null reference exception.
I think what you're trying to do is convert the string value to the type of value in the setting type. You don't need to use reflection for that. I'd recommend adding a read only property to your SettingDataValue object:
public object Value
{
get
{
return SomeMethodThatConvertsYourStringValueToTarget();
}
}
Then a private method to actually do the conversion.
private object SomeMethodThatConvertsYourStringValueToTarget();
{
switch (SettingType)
{
case "TimeSpan":
//conversion code
break;
}
}
Then change your getSettingsFromDb method to return object instead of dynamic. Then you can use it like:
TimeSpan ts = (TimeSpan)getSettingsFromDb("SMTimeStart");
Alternatively you may create a method for each data type so you don't have to case it when using it. So you could use it like:
TimeSpan ts = getTimeStampFromDb("SMTimeStart");

Passing parameters to a constructor, which are properties of an object class

I'm very new to C#, and the realm of programming. I've been carrying out some exercises in books and YouTube videos to wrap my head around many of these concepts.
Currently, I'm stuck on this issue. I have a small application for a Consignment Shop, and I was working on removing the hard coded sample data, and having the program read data from text files.
Here is my Vendor class:
public class Vendor
{
public string FirstName { get; set; }
public string LastName { get; set; }
public Vendor(string firstName, string lastName)
{
FirstName = firstName;
LastName = lastName;
}
}
This essentially takes my .csv file of Vendors and pushes them into a string array, creates the object and fills it's properties with array values, then adds the item to a list of type Vendor. This method throws no errors.
private void ReadFromFile()
{
string line = "";
while ((line = myReader1.ReadLine()) != null)
{
string[] data = line.Split(',');
Vendor v = new Vendor(data[0], data[1]);
store.Vendors.Add(v);
}
}
When I try this same solution for adding Items to a list, I would like to pass in the "Owner" of the item, which is a property of type Vendor, located in my Items class. Since I couldn't get a working solution on passing an object as a parameter in constructor, I decided to stick with passing formal data types. I basically want to use the Vendor's properties of First Name & Last Name, and set those as the Item Owner's first and last name.
public class Item
{
public string Title { get; set; }
public decimal Price { get; set; }
public Vendor Owner { get; set; }
public Item(string title, decimal price, string fName, string lName)
{
Title = title;
Price = price;
Item.Owner.FirstName = fName; // this is what I want to do
Item.Owner.LastName = lName; // throws objref error
}
}
//Input file format: title,price,fname,lname
while ((line = myReader2.ReadLine()) != null)
{
string[] data2 = line.Split(',');
decimal price = decimal.Parse(data2[1]);
Item i = new Item(data2[0],price,data2[2],data2[3]);
store.Items.Add(i);
}
The strings make it into the array, but when I run the debugger and check my store.Items List, every property value is set except for Owner, which is null.
I know one solution could be to somehow combine fName+lName into one string, but I'm having a hard time understanding how my Item constructor needs to be set up in terms of which parameters it will accept. No matter what I try, the Oner property is never received a value, which causes the rest of my application to crash.
I've been working at this for a few hours, but I can't seem to come up with a working solution, or even a workaround to this scenario.
Any help is greatly appreciated.
Thanks!
I don't think your code even compiles, but what you want is this:
Owner = new Vendor(fName, lName);
This essentially creates a Vendor instance and assigns it to the Owner variable. Owner is otherwise uninitialized and null, that's why you get the exception.
instead of this:
Item.Owner.FirstName = fName; // this is what I want to do
Item.Owner.LastName = lName; // throws objref error
You have exception because Item.Owner is actually not created.
Fix it:
public Item(string title, decimal price, string fName, string lName)
{
Title = title;
Price = price;
Item.Owner = new Vendor(fName, lName);
}
Also: why do you write 'Item.Owner'? It isn't seemed to be static. Use just Owner.
In Java, if a class is a member of another class, you initialise it with new.
So in your constructor, you'd do the following:
public Item(string title, decimal price, string fName, string lName)
{
Title = title;
Price = price;
Owner = new Vendor(fName, lName);

When searching for a row, counts come back as 0

I am currently doing the following to try and get back a particular row in a data table based on the date time. The issue I am running into is when I run the code I continuously get 0 back for my number of rows and I am not sure as to why. Here is some code to that maybe someone can pick apart.
var myDay = new AnalysisDay(uniqueDate.Date, null, null, null, null);
var daysList = new List<AnalysisDay>();
foreach(var uniqueDate in uniqueDateList)
{
var myDay = new AnalysisDay(uniqueDate.Date, null, null, null, null);
var curDate = uniqueDate;
//This is the area where the rows come back 0 everytime "Start Date Time"
//occasionally has DBNull values
var curDatesRows = analysisInfo.Tables[0].Select("StartDateTime = #{0}#", curDate.ToShortDateString()));
}
This is the custom class that is referenced throughout,
public class AnalysisDay
{
public DateTime? Date { get; set; }
public DateTime? Time { get; set; }
public string Name { get; set; }
public int? CarNumber { get; set; }
public int? RunId { get; set; }
public ObservableCollection<AnalysisDay> Items { get; set; }
public AnalysisDay(DateTime? date, DateTime? time, string strName, int? number, int? runId)
{
Date = date;
Time = time;
Name = strName;
CarNumber = carNum;
RunId = runId;
Items = new ObservableCollection<AnalysisDay>();
}
}
If I have left anything out or need to provide more information please let me know and I will update this as soon as possible.
Something about the comparison must be failing. I usually use LINQ to query instead:
var curDatesRows
= dt.Rows.Cast<DataRow>()
.Where(x => x.Field<DateTime?>("StartDateTime").HasValue
&& x.Field<DateTime>("StartDateTime").Date == curDate.Date);
I tested this out on some sample data - it will filter out rows with a null value.
Note that if curDate has a time portion, and it doesn't match exactly what's in the table, then you won't get any rows unless you use .Date to drop the time portion when doing the comparison.
It looks like you are passing a short date string as the filter against a column containing date time values (which include time components). I believe that either no date in the startDateTime column will match the filter, or only values where the time component is all zeros (which is unlikely, unless you are modifying the times before persisting.
Without additional information, it's hard to tell. Can you show us some sample data from the table? Specifically, the startDateTime column?

Input string was not in the correct format C# ASP.NET

I am new to programming and currently working on a C# asp.net website that populates Telerik RadComboBoxes from a database on_load.
I have a form that has 15+ ComboBoxes and when I select values from those ComboBoxes those ComboBox selections must be used to search through a really large table in my database. A gridView will display the returned data.
I have used the same format of code throughout the rest of my project and it works perfectly, But when I select an item from my "Location" DropDownBox to search through my database I get the error 'Input string was not in a correct format' and I cant figure out why
here is my Location.cs Class
region Properties
[Key]
public int LocationID { get; se; }
[Column("Location")]
public string LocationName { get; set; }
private int? _ParentLocationID;
[Column]
public int? ParentLocationID
{
get
{
return _ParentLocationID;
}
set
{
if (value == 0)
{
_ParentLocationID = null;
}
else
{
_ParentLocationID = value;
}
}
}
[Column]
public int SiteID { get; set; }
[Column]
public bool Active { get; set; }
region Method
public static IEnumerable<Location> LoadActiveLocations(int siteID)
{
iThNkContext db = new iThNkContext();
var LocationList = (from l in db.Locations
where(l.SiteID == siteID && l.Active == true)
orderby l.LocationID
select l).ToList();
return LocationList;
}
And here is the code I am using in my .aspx file
RadTreeView trvLocation = (RadTreeView)cboLocation.Controls[2].FindControl("trvLocation");
if (trvLocation.SelectedValue != "")
{
var locationID = Convert.ToInt32(trvLocation.SelectedValue); //Error
predicates.Add(p => p.LocationID == locationID);
}
On the //Error line is where I am getting the 'Input string was not in the correct format' error, any suggestions please. I cant understand why I am having this problem
thank you in advance
if you expect the locationID to be a number, make sure the the value for each items in the combobox can be converted to numbers. otherwise, even if you use tryparse, your page won't run correctly.
P/S: TryParse will only avoid the error and won't assign the selectedvalue to locationID, and hence, break you logic.
It looks like your LocationID is a nullable value - you cannot convert a null value to an Int32. You need to ensure that each value member bound to the drop down list is not a null value but is a valid integer.

Categories

Resources