Access the data in the dictionary when the item is an object? - c#

So I am lost on how to send data back to the object once it is added to the dictionary.
With this data structure that I made http://pastebin.com/HicZMzAt for full code
I have
public class Computer
{
public Computer() { }
public Computer(int _year)
{
dropOffDate = DateTime.Now;
RepairFinished = false;
Year = _year;
}
private DateTime dropOffDate;
public bool RepairFinished;
private readonly int Year;
public static string Plate;
private string make;
public string Make
{
get { return make; }
set { make = value; }
}
public string Model { get; set; }
public string ComputerTicketId { get; set; }
public bool IsLaptop { get; set; }
public Location Location { get; set; }
public int HoursWorked { get; set; }
public double PartsCost { get; set; }
public DateTime DateFinished { get; set; }
// public virtual double TotalCost { get { TotalCost = (this.HoursWorked * 50) + PartsCost; } set; }
public void ComputerPickUp()
{
Console.WriteLine("Cost is {0:C} ", this.HoursWorked);
RepairFinished = true;
}
where I want to calculate the different cost for repairs for each dropped of system.
public class Laptop : Computer
{
public bool HasCharger { get; set; }
public Laptop(int year, bool _HasCharger)
: base(year)
{
HasCharger = _HasCharger;
}
//TODO overide for COST ! + 10
and I have a desktop class also were the cost of repair is cheaper for Desktop systems.
But I am using
public static class Repair
{
public static Dictionary<string, object> RepairLog { get; set; }
}
to track the repairs
and now I am lost in the UI part of the program to get the data to figure out the pricing.
public class RepairUI
{
....edited
Repair.RepairLog = new Dictionary<string, object>();
....
Computer = new Desktop(ComputerYear, HasLcd);
And that is how I am lost about the way to handle the data , the class data for each repair unit (desktop / NBK ) is organized in the dictionary and now I want to get the data and edit the repair cost of the object , but I can't seem to figure out how to reach the object.
So how could I ask upon pick up hours worked and calculate the info for the unit ?

This sounds like a great moment to use an Interface!
public Interface IRepairable
{
double GetRepairCost();
}
Then redefine Computer
public class Computer : IRepairable
{
public double GetRepairCost()
{
return (this.HoursWorked * 50) + PartsCost;
}
}
and Laptop
public class Laptop : Computer
{
public new double GetRepairCost()
{
return base.GetRepairCost() + 10;
}
}
and Repair
public static class Repair
{
public static Dictionary<string, IRepairable> RepairLog { get; set; }
}
And now you have a dictionary of things that you can call GetRepairCost() on! These could be Computers or Laptops or a mix, it doesn't matter to the RepairLog!

Related

C# how to check array in list

I'm building a Worker service for Windows who gets data from another program on the system.
at this point i have all data that is need now i want to keep a list with up to date data.
When i run the application for the Zones i get System.Int32[] what i would love to see is the data from System.Int32[]
how to obtain this?
List<BroadcastModel> activeOmroep = new List<BroadcastModel>();
for (int o = 0; o < webcontent.Length; o++)
{
for (int i = 0; i < webcontent[o].Zones.Length; i++)
{
}
activeOmroep.Add(new BroadcastModel
{
Id = webcontent[o].Id,
Name = webcontent[o].Name,
Recording = webcontent[o].Recording,
Zones = webcontent[o].Zones
}) ;
My BroadcastModel class looks like the following:
public class BroadcastModel
{
public int Id { get; set; }
public string Name { get; set; }
public int[] Channels { get; set; }
public bool Recording { get; set; }
public int Type { get; set; }
public int Volume { get; set; }
public int[] Zones { get; set; }
}
Thanks in advance.
for testing purpose i added the following:
foreach (var omroep in activeOmroep)
{
Console.WriteLine("Broadcast ID: " + omroep.Id);
Console.WriteLine("Broadcast Name: " + omroep.Name);
Console.WriteLine("Broadcast is recording: " + omroep.Recording);
Console.WriteLine("Broadcast Zones: " + omroep.Zones);
Console.WriteLine("****************************");
}
but then i got the system.int32[]
Whenever you are printing data using Console.WriteLine(), it calls .ToString() method, if .ToString() is not overridden then it calls Object.ToString() method. Object.ToString() prints type in the string format.
In your case Console.WriteLine("Broadcast Zones: " + omroep.Zones); is printing System.Int32[], because it is calling ToString() method with the basic behavior.
To solve your issue, I would suggest to Override ToString() method in BroadcastModel class and return string which you want to print.
To print array elements, use string.Join() method.
Concatenates the elements of a specified array or the members of a
collection, using the specified separator between each element or
member.
public class BroadcastModel
{
public int Id { get; set; }
public string Name { get; set; }
public int[] Channels { get; set; }
public bool Recording { get; set; }
public int Type { get; set; }
public int Volume { get; set; }
public int[] Zones { get; set; }
public override string ToString()
{
return $"ID : {this.Id}, \nName: {this.Name} \nIs recording: {this.Recording} \nZones : {string.Join(", ", this.Zones)}";
}
}
Now you can print List<BroadcastModel> using foreach loop,
foreach(var broadcastmodel in activeOmroep)
Console.WriteLine(broadcastmodel);

Insert data into SQL table from two forms C# winform

I am trying to insert data from frm1 and frm2 into SQL Server at the same time. frm1 contains product information (barcode, qty , price, vat, total etc) and frm2 (contains payments information like cash and change). The idea is that when the user clicks the btnfrm2 the data from frm1 should be passed into frm2 (but not displayed), and in frm2 the user gives the payment info (cash and change) and after clicking btnsave the data from frm1 and frm2 should be inserted into the database.
I created a class, and a method to pass data to frm2.
internal void mbushe(string[] args)
{
for (int i = 0; i < dataTable.Rows.Count; i++)
{
arka_data ad = new arka_data();
ad.NR = int.Parse(txtnrfatures.Text);
ad.VLERATVSHTOTAL = float.Parse(textBox1.Text);
ad.BARKODI = int.Parse(dataTable.Rows[i][0].ToString());
ad.EMERTIMI = dataTable.Rows[i][1].ToString();
ad.SASIA = int.Parse(dataTable.Rows[i][2].ToString());
ad.CMIMI = int.Parse(dataTable.Rows[i][3].ToString());
ad.TVSH = int.Parse(dataTable.Rows[i][4].ToString());
ad.NENTOTALI = float.Parse(txttotali.Text);
ad.ZBRITJA = float.Parse(txtzbritja.Text);
ad.TOTALI = float.Parse(totali.Text);
ad.KOHA = DateTime.Now;
ad.KASIERI = lbluser.Text;
ad.KLIENTI = cmbklienti.Text;
ad.VLERAETVSH = float.Parse(dataTable.Rows[i][7].ToString());
ad.VLERAPATVSH = float.Parse(dataTable.Rows[i][6].ToString());
ad.NRATIKUJVE = int.Parse(lblnumri.Text);
ad.TOTALIPCS = float.Parse(dataTable.Rows[i][5].ToString());
}
}
public class arka_data
{
public int NR { get; set; }
public int BARKODI { get; set; }
public string EMERTIMI { get; set; }
public int SASIA { get; set; }
public float CMIMI { get; set; }
public float TVSH { get; set; }
public float TOTAL { get; set; }
public float NENTOTALI { get; set; }
public float ZBRITJA { get; set; }
public float TOTALI { get; set; }
public DateTime KOHA { get; set; }
public string KASIERI { get; set; }
public string KLIENTI { get; set; }
public float VLERAETVSH { get; set; }
public float VLERAPATVSH { get; set; }
public int NRATIKUJVE { get; set; }
public float TOTALIPCS { get; set; }
public float VLERATVSHTOTAL { get; set; }
}
and in the second form I will use the elements of method( from first form)
cmd.Parameters.Add(new SqlParameter("#nrfatures", mbushe.NR);
cmd.Parameters.Add(new SqlParameter("#klienti", mbushe.Barkodi)); etc
while mbushe is the method from first form
Best if your forms use MVP pattern, AKA inherit from interface. Example
public class MyForm1 : Form, IView1
{
public string SomeData { get { return MyControl1.Text } }
. . . .
}
public class MyForm2 : Form, IView2
{
public string SomeOtherData { get { return MyControl1.Text } }
. . . .
}
Then you create persister, which collects the data from both forms and saves
public class FormDataPersister
{
private IView1 _v1;
private IView2 _v2;
public class FormDataPersister(IView1 form1Data, IView2 form2Data)
{
_v1 = form1Data;
_v2 = form2Data;
}
public void Save()
{
// HERE collect your data into parameters and SAVE
// EXAMPLE
. . . . .
cmd.Parameters.Add(new SqlParameter("#klienti", _v1.Barkodi));
cmd.ExecuteNonQuery();
}
}
I would recommend that you build an object from the data on the UI and then either
Pass it along (from form to form) while filling it with more and more information or
Store it in some kind of repository so every part of the code-base has access to (preferred)
When the user then clicks the btnsave button on Form2, you simply call a code that persists that object.
This way you are keeping the form, its data, and the database interaction logic separate from each other.

Storing/retrieving a JSON string in the database making it easy to work with in code

I have a c# object 'Product' with a property called: Offset
In the database the field is of type nvarchar(50)
I will be storing a JSON value in it such as the following: { "y": 0, "m": 0, "d": 0 }
I would like to know a good way of working with a property like this in my code. Here is how I currently am doing it:
public class Product
{
public int Id {get; set;}
public string Description {get; set;}
public decimal Price {get; set;}
public int OffsetYears { get; set; }
public int OffsetMonths { get; set; }
public int OffsetDays { get; set; }
public string Offset
{
get
{
Offset offset = new Offset()
{
Y = OffsetYears,
M = OffsetMonths,
D = OffsetDays
};
return JsonConvert.SerializeObject(offset);
}
set
{
OffsetObj offset = JsonConvert.DeserializeObject<Offset>(value);
OffsetYears = offset.Y;
OffsetMonths = offset.M;
OffsetDays = offset.D;
}
}
private class OffsetObj
{
public int Y { get; set; }
public int M { get; set; }
public int D { get; set; }
}
}
So then when I accept values from the User in the UI I would set the OffsetYears, OffsetMonths, and OffsetDays properties.. So in my repository I can just save Offset.
And when retrieving values from the database I will simply work with OffsetYears, OffsetMonths, and OffsetDays properties in my code.
Is there a better way to handle this sort of thing? I just feel like I am not utilizing all of my c# resources. Like what if another developer accidentally sets Offset through the code assuming any format of string can go in it.
Or am I better off just creating 3 separate integer fields in the database and avoiding all of this...
I would hold the values in a field of your private type. Consider this approach:
public class Product
{
private OffsetObj _offset = new OffsetObj();
public int Id { get; set; }
public string Description { get; set; }
public decimal Price { get; set; }
public int OffsetYears
{
get { return _offset.Y; }
set { _offset.Y = value; }
}
public int OffsetMonths
{
get { return _offset.M; }
set { _offset.M = value; }
}
public int OffsetDays
{
get { return _offset.D; }
set { _offset.D = value; }
}
public string Offset
{
get
{
return JsonConvert.SerializeObject(_offset);
}
set
{
_offset = JsonConvert.DeserializeObject<OffsetObj>(value);
}
}
private class OffsetObj
{
public int Y { get; set; }
public int M { get; set; }
public int D { get; set; }
}
}
This way, the field offset will hold the values for the offset.
Like what if another developer accidentally sets Offset through the code assuming any format of string can go in it.
JsonConvert will throw a JsonReaderException if trying to set the Offset property to a string that does not match JSON-format. In my opinion this is expected. To clarify further, you could name your property to OffsetJson.
However, I fail to see the benefit in this simple case to store your information as JSON. If you are using a relational database, you may as well just store your values in separate columns.

Organizing data in a class

I have a question regarding the way I'm storing data in my application, keep in mind I'm not too experienced with C#. So, I am grabbing data from a file and able to print it all out using a foreach loops
try
{
var doc = new HtmlDocument();
doc.LoadHtml(htmlDoc);
var i = 0;
foreach (HtmlNode row in doc.DocumentNode.SelectNodes("//tr"))
{
if (i <= 6) { Console.Write("[Type1]"); }
if (i >= 7 && i <= 12) { Console.Write("[Type2 i + " : "); }
if (i >= 13 && i <= 23) { Console.Write("[Type3] i + " : "); }
if (i >= 24 && i <= 33) { Console.Write("[Type4]" + i + " : "); }
if (i >= 34 && i <= 39) { Console.Write("[Type5]" + i + " : "); }
if (i > 38 || i < 1) { Console.Write("Error LTZ or GTV"); }
Console.Write(row.Elements("td").First().InnerText);
Console.Write(" - ");
Console.WriteLine(row.Elements("td").Last().InnerText);
i++;
}
}
This part works fine, it prints them all out with the appropriate tag in front of the data. What I am trying to accomplish is instead of printing the data out I want to store it in my class. I have it modeled like this currently
public class House
{
//Downstairs
public int DBedrooms {get; set; }
public int DKitchens {get; set; }
public int DLiving { get; set; }
//upstairs
public int UBedrooms { get; set; }
public int UKitchens { get; set; }
public int ULiving { get; set; }
//Neighborhood
public string NSchool { get; set; }
public int NSchoolDist { get; set; }
public int NCrime { get; set; }
...
...
...
}
there's about 40 public ints in the class currently and I'm just wondering what a better way to store the data would be!
Every structure that can have duplicates should have their own class instead of just declaring a lot of properties, and I personally like storing such structures in a list. you would also want to add them to the list in the right order so you don't mistake the upstairs for the downstairs.
For the ability to have many floors in a house i would organize like so:
public class Floor {
public int DBedrooms {get; set; }
public int DKitchens {get; set; }
public int DLiving { get; set; }
}
public class House {
public List<Floor> Floors{get;set;}
public string NSchool { get; set; }
public int NSchoolDist { get; set; }
public int NCrime { get; set; }
}
FYI: if you might be able to use a Repeater instead of programmably creating html (http://www.w3schools.com/aspnet/aspnet_repeater.asp), although I don't know if it fits your use case.
Edit: also if you are the one creating the source files then consider deserialization from xml.
First of all, what is the use case of the object? If it's simply a data transfer object then leaving it as it is should be fine. However if parts of the object are to be used throughout the application then you could break it down into pieces like so:
public class Downstairs : Floor
{
public IList<Room> Rooms { get; set;}
}
public class Upstairs : Floor
{
public IList<Room> Rooms { get;set; }
}
public class House
{
public HouseOwner Owner { get;set; }
public readonly IList<Floor> Floors { get; private set;}
public House(HouseOwner owner, IList<Floor> floors)
{
this.Owner = owner;
this.Floors = floors;
}
public void AddFloor(Floor floor)
{
this.Floors.Add(floor);
}
public int TotalFloors()
{
return this.Floors.Count();
}
}
By modelling your data like this each object encapsulates its own and properties data making it a little more organised than a large generalised class.

List orderby nested property

I have some data coming back from a web service, which I have mapped to the following classes:
public class Webinar {
public string Title { get; set; }
public string Description { get; set; }
...
public List<TimeZone> TimeZones { get; set; }
}
public class TimeZone {
public TimeSpan GmtOffset { get; set; }
public List<Session> Session { get; set; }
}
public class Session {
public int WebinarKey { get; set; }
public DateTime StartTime { get; set; }
public TimeSpan Duration { get; set; }
}
Hopefully it's fairly clear what is going on: any one webinar can have multiple time zones which in turn holds the individual sessions.
I have a list of webinars List<Webinar> webinars = ... which is populated with data. On the page I would like to present webinars grouped by time zone (easy) and then sorted by their start time.
My problem: the sessions are not necessarily ordered by StartTime when I receive the data, which I would like to do. I have the following code which does work, but recreating each object and mapping out all it's properties is a PITA, is there a nicer way to do what I want?
List<Webinar> webinarsWithOrderedSessions = new List<Webinar>();
foreach (Webinar webinar in mappedWebinars)
{
Webinar currentWebinar = new Webinar
{
Title = webinar.Title,
...
TimeZones = new List<TimeZone>()
};
foreach (Webinar.TimeZone timeZone in webinar.TimeZones)
{
Webinar.TimeZone currentTimeZone = new TimeZone
{
Location = timeZone.Location,
Sessions = new List<Session>()
};
currentTimeZone.Sessions = timeZone.Sessions.OrderBy(session => session.StartTime).ToList();
currentWebinar.TimeZones.Add(currentTimeZone);
}
webinarsWithOrderedSessions.Add(currentWebinar);
}
UPDATE
Building upon the suggestion by #Max, why might this bit of code not work? It doesn't seem to add the sessions at all. I don't necessarily need two properties, so I thought I'd just apply your suggestion directly to the main property.
public class TimeZone
{
private List<Session> _sessions;
public List<Session> Sessions
{
get { return _sessions.OrderBy(s => s.StartTime).ToList(); }
set { _sessions = value; }
}
}
You can try with this:
public class TimeZone
{
private List<Session> _ordered;
public TimeSpan GmtOffset { get; set; }
public List<Session> Session
{
get
{
return this._ordered;
}
set
{
if (value != null)
{
this._ordered = value.OrderBy(p => p.StartTime);
}
}
}
}
I has improved the answer using explicit set and get
Try this way:
var webinarsWithOrderedSessions = (from x in mappedWebinars
from y in x.TimeZones
from s in y.Session
orderby s.StartTime
select x).ToList();

Categories

Resources