I am fairly new to programming and am trying to wrap my head around classes. I have created a class like the following:
public class HistoricalEvents
{
public DateTime historicDate { get; set; }
public string historicEvent { get; set; }
}
I want to be able to go into a MySQL database, pull multiple events, and then display those events onto the screen. How do you create multiple HistoricalEvents from MySQL and then iterate through them to display them onto a screen?
First, you need a class representing a single event, preferably named in the singular (eg HistoricalEvent instead of HistoricalEvents).
Then you can create a List<HistoricalEvent> like so:
public class HistoricalEvent
{
public DateTime historicDate { get; set; }
public decimal historicEvent { get; set; }
}
List<HistoricalEvent> historicalEvents = new List<HistoricalEvent>();
historicalEvents.Add(new HistoricalEvent());
// ... etc etc ...
Once you have your list, you can iterate it like so:
foreach (HistoricalEvent historicalEvent in historicalEvents)
{
// "historicalEvent" contains the current HistoricalEvent :)
}
Creating objects from a MySQL database is a lot more involved. If you want to jump in, try this tutorial (provided by Microsoft), and perhaps look into linq to objects, but I would suggest becoming more familiar with C# first :)
Edit:
That sounds a bit terse, so here's a similar example:
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
List<Person> people = new List<Person>();
people.Add(new Person()
{
Name = "Dave",
Age = 43
});
people.Add(new Person()
{
Name = "Wendy",
Age = 39
});
foreach (Person person in People)
{
Console.WriteLine(person.Name) // "Dave", then "Wendy"
}
This uses the Connector/Net ADO.Net provider:
var list = new List<HistoricalEvent>();
using (var cn = new MySqlConnection())
{
cn.Open();
var sql = "SELECT Date, Event FROM HistoricalEvents";
using(var cm = new MySqlCommand(sql, cn))
using(var dr = cm.ExecuteReader())
{
while (dr.Read)
list.Add(new HistoricalEvent
{
historicDate = dr.GetDate(0),
historicEvent= dr.GetString(1)
});
}
}
foreach (var item in list)
Console.WriteLine("{0}: {1}",item.historicDate,item.historicEvent);
Related
I am a junior developer with very little experience using a class. I have create a class which looks like this.
public class Employee
{
public string EmpID { get; set; }
public string Hours { get; set; }
public string Minutes { get; set; }
public string Pages { get; set; }
public string Certs { get; set; }
public double HourlyRate { get; set; }
}
}
I use this code to populate the Class via the click of an asp button
Employee emp1 = new Employee();
emp1.EmpID = ddlSpecialist.SelectedValue;
emp1.Hours = txtDetailsHours.Text;
emp1.Minutes = txtDetailsMinutes.Text;
emp1.Pages = TxtDetailsPages.Text;
emp1.Certs = txtDetailsCertified.Text;
emp1.HourlyRate = HR;
I assume everything is working and I am populating the class with records. I now want to build a list so can pull the data from the Class. And this is now where I am stuck I instantiate the list using
List<Employee> Emp = new List<Employee>();
foreach (var item in Employee)
{
}
But from there I cannot figure out how to add records from the class.
I tried to build a foreach loop but I get a error "Employee is a type, which is not valid in the given context" I can find several example where the values I am trying to get from the class are hard coded but nothing where the data comes from the class.
The goal is to have a a group of textboxes with data. When the users provides the data in those boxes they would click a button that would take the values in the textboxes and store it in the class. The code behind would then clear the textboxes of their values and the user can now enter another batch of information that would get added to the class.
When the user was done entering the records I would want to loop thru the class and for each record in the class perform some simple mathematical calculations. So it kind of works like a calculator.
edit
Okay, your new edit makes things a little clearer, but you still don't say what you wish to do with your data once it's been added to your Employee class.
Assuming that you're using ASP.NET, your code is probably structured in a pattern known as MVC, where M(for Model) is your Employee class, your ASP page is the V (for View) and you'll have another class/file that is the C (Controller).
Your UI page is used to populate an instance of Employee, as you've said, this is then passed through the controller to be stored, typically in a database of some sort.
The controller should provide either an empty instance of Employee to the View when it opens.
The "submit" button should trigger/call a Task in the controller to store the Employee instance. This may be on a list locally in the Controller or by direct call to the database, depending on your caching protocol.
Once stored the Controller should provide the View with a new, empty Employee instance.
Does this seem to make sense and is this relevant to your situation?
original answer below
Your question is a little unclear.
If you are gathering your data to populate your Employee instance from an ASP page and then looking at storing that data onto a remote server then how that is done will be dependent on your remote API.
You could get all of the data from any class properties
Something like this?
using System.IO;
using System;
using System.Text;
using System.Reflection;
using System.Linq;
class Program
{
static void Main()
{
Employee emp1 = new Employee();
emp1.EmpID = "1234";
emp1.Hours = "46";
emp1.Minutes = "32";
emp1.Pages = "5";
emp1.Certs = "none";
emp1.HourlyRate = 12.45;
StringBuilder sb = new StringBuilder();
sb.Append($"{emp1.GetType().Name}:");
var props = emp1.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)
.Where(p => p.CanRead);
foreach (var p in props)
{
sb.Append($"{p.Name}=");
sb.Append($"{p.GetValue(emp1).ToString()};");
}
Console.WriteLine(sb.ToString());
}
}
Output:
Employee:EmpID=1234;Hours=46;Minutes=32;Pages=5;Certs=none;HourlyRate=12.45;
On this way you can add values to list.
public class Employee{
public string EmpID { get; set; }
public string Hours { get; set; }
public string Minutes { get; set; }
public string Pages { get; set; }
public string Certs { get; set; }
public double HourlyRate { get; set; }
};
public static void Main()
{
List<Employee> employees = new List<Employee>()
{
new Employee() {EmpID = 1},
new Employee() {EmpID = 2}
};
//or this way
List<Employee> employees = new List<Employee>();
employees.Add(new Employee() {EmpID = 1});
employees.Add(new Employee() {EmpID = 2});
foreach(var employee in employees)
{
Console.WriteLine(employee.EmpID);
}
}
I have four classes :
public class Customer
{
public string FirstName { get; set; }
public string LastName { get; set; }
public List<Product> Product { get; set; }
}
public class Product
{
public int ProductNumber { get; set; }
public string ProductColor { get; set; }
}
///////////////////////////////////////////////
public class Customer_
{
public string FirstName { get; set; }
public string LastName { get; set; }
public List<Article> Article { get; set; }
}
public class Article
{
public int ArticleNumber { get; set; }
public string ArticleColor { get; set; }
}
And one instance :
var Cus = new List<Customer>
{
new Customer()
{
FirstName = "FirstName1",
LastName = "LastName1",
Product = new List<Product>
{
new Product()
{
ProductColor = "ProductColor1",
ProductNumber = 11
}
}
},
new Customer()
{
FirstName = "FirstName2",
LastName = "LastName2",
Product = new List<Product>
{
new Product()
{
ProductColor = "ProductColor2",
ProductNumber = 12
}
}
}
};
I want to create a new object List<Customer_> with the value of my instance Cus. For example Customer.FirstName = Customer_.FirstName, Customer.Product.ProductColor = Customer_.Article.ArticleColor etc
What is the best way to do this easily, could one use a Dictionary?
Mapping can be accomplished through the use of an Interface.
Define an interface(s) which provide a mapping of logically named properties such as the common color properties you mention:
// Some entities have different named properties but can be joined
// using those properties. This interface shows a common color which
// when implemented will route the processing to a common shared property
// which reports and sets the associated color.
public interface IDefinedColor
{
string Color { get; set; }
}
If you have to create partial classes for Product and Article and have them adhere to said interfaces. Hint if using an entity mapper such as EF this is a great way to do such maping using partials. Implement implement the interface and hook up the commonality:
// Holds the common properties for future processing.
public partial class Product : IDefinedColor
{
public string Color
{
get { return ProductColor; }
set { ProductColor = value; }
}
}
Then work off of the IDefinedColor mapped implementations as needed.
By using interfaces one is letting all future developers know of the contract which specifies a business logic equality in the properties and it is not hidden in other joining classes.
You could create a mapper extension class
public static class MapperExtension
{
public Customer_ Convert(this Customer customer)
{
return new Customer_()
{
FirstName = customer.FirstName,
LastName = customer.LastName,
Article = customer.Product.Convert()
};
}
public static List<Article> Convert(this List<Product> products)
{
return products.Select(x=> new Article(){
ArticleNumber = x.ProductNumber,
ArticleColor = x.ProductColor
};
}
}
make sure you reference the proper namespace where you place the extension class.
Call the code like this
Where customers is a List filled from your code
List<Customer_> convertedCustomers_ = customers.Select(x=> x.Convert()).ToList();
It depends on the relationhip between those components but I would simply add constructor to Customer_ that accepts a Customer object. And then you invoke that do perform the conversion. e.g.
public class Article
{
public Article(Product source)
{
this.ArticleNumber = source.ProductNumber;
this.ArticleColor = source.ProductColor;
}
}
public class Customer_
{
public Customer_(Customer source)
{
this.FirstName = source.FirstName;
this.LastName = source.LastName;
this.Article = source.Product.Select(o => new Article(o)).ToList()
}
...
}
//and finally to convert the list you can do something like
//initial list
var Cus = new List<Customer>() { ... etc. }
/converted list
var Cus_ = Cus.Select(o => new Cusomter_(o)).ToList();
Edit: I see from your comment above that you actually have 100 properties to map. I can see this is a pain. But if you have complex transformations like Product to Article then I would still go the manual route as above so you can be completely clear about what is going on. Alternatively you could look to use inheritance to redesign your objects with common base classes or interfaces, that would probably make mapping easier.
I want to create a list based off the query that gets passed into my Method. My issue is determining how to add those items to a list that I return as a result list. The following is the code that includes my list and what will hopefully be the way I populate that list...
public void QueryInto<T>(ref List<T> returnType, string queryString, string[] parameters = null)
{
try
{
// Setup the query.
SetupCommand(queryString);
// Setup the parameters.
AddParameters(parameters);
// Execute the reader.
OpenReader();
// Make sure the statement returns rows...
if (reader.HasRows)
{
// For each row, do this...
while (reader.Read())
{
// TODO: use datamapping to map to model and add items to list...
}
}
}
Perhaps there is a better way of doing this, but so far this is the direction Google Has directed me!
you can use Dapper for this.
example useage;
public class Dog
{
public int? Age { get; set; }
public Guid Id { get; set; }
public string Name { get; set; }
public float? Weight { get; set; }
}
var guid = Guid.NewGuid();
var dog = connection.Query<Dog>("select Age = #Age, Id = #Id", new { Age = (int?)null, Id = guid });
I just want to get some opinions on the most efficient and quickest way to populate my composite class using the EF4.0. I have a parent class which has a structure similar to the class below. It mirrors my database structure.
public class Person
{
public string FirstName { get; set; }
........
public Address WorkAddress { get; set; }
public IList<Account> Workspace { get; set; }
}
public class Address
{
public string FirstName { get; set; }
......
}
public class Account
{
public string SortCode { get; set; }
public IList<string> TransactionHistory {get; set;}
......
}
So, at this moment in time I pull back all the 'Persons' from the EF and I loop through each of them and populate the Address and Accounts for each. Lazy loading is enabled, so I have to encapsulate all my loops in the using statement or my Accounts will be empty when I try to iterator through them. So, can I disable lazy loading for this call only or should approach the population of my list of persons in another manner.
using (var entities = new PersonEntities())
{
var dbPeople = (from person in entities.Persons
select person).ToList();
foreach(var person in dbPeople)
{
foreach(var account in person.Accounts)
{
// In here I populate my 'Person' business object account and add it to my collection to return.
}
}
}
If I got you right, you're going to include the relation keeping the LazyLoading enabled. You can do this for the query using the Include method:
using (var entities = new PersonEntities())
{
var dbPeople = entities.Persons.Include("Accounts").ToList();
foreach(var person in dbPeople)
{
//Do nothing with Accounts if the relation is mapped correct
}
}
EDIT:
Also you can disable LazyLoading for the created PersonEntities instance's lifetime:
using (var entities = new PersonEntities())
{
entities.Configuration.LazyLoadingEnabled = false;
//...
}
I have 2 classes with different properties in each. Also I have a collection of one set of objects of the class A. Now I want to copy these to an array of objects of Class B.
The 2 classes are not inter related and also the fields are different in each. SO i have to explicitly map the fields i want to copy. Right now I am using a foreach to copy individual element. Is there a shorter way to accomplish this.
This is the class B
public class Event
{
public string EventOriginTime { get; set; }
public string EventReceivedTime { get; set; }
public int EventCode { get; set; }
public string CardNumber { get; set; }
public string ReaderName { get; set; }
}
First class A also will appear something like this but that is a 3rd party class.
Current solution I have is:
List<Event> listOfEvents = new List<Event>();
foreach (var eachEvent in eventsFromArgus)
{
listOfEvents.Add( new Event
{
ReaderName = eachEvent.DeviceName,
EventCode = eachEvent.EventCode,
EventReceivedTime = eachEvent.ReceiveTime.ToString(),
EventOriginTime = eachEvent.OriginTime.ToString(),
CardNumber = eachEvent.CredentialIdentifier
});
}
You could use LINQ:
List<event> listOfEvents =
(from eachEvent in eventsFromArgus
select new Event(
ReaderName = eachEvent.DeviceName,
EventCode = eachEvent.EventCode,
EventReceivedTime = eachEvent.ReceiveTime.ToString(),
EventOriginTime = eachEvent.OriginTime.ToString(),
CardNumber = eachEvent.CredentialIdentifier)).ToList();
But that's not terribly different from what you already have.
Or, you could look into something like AutoMapper.
Another approach is to pass the third party object directly into the Event class' constructor:
public class Event
{
private readonly ThirdPartyClass _eventFromArgus;
public Event(ThirdPartyClass eventFromArgus)
{
_eventFromArgus = eventFromArgus;
}
public string ReaderName { get { return _eventFromArgus.DeviceName; } }
// etc.
}
Then you can just do this:
var listOfEvents = eventsFromArgus.Select(eachEvent => new Event(eachEvent));
also with linq as Jim suggested but a bit different
var listOfEvents = eventsFromArgus.Select(eachEvent =>
new Event( ReaderName = eachEvent.DeviceName,
EventCode = eachEvent.EventCode,
EventReceivedTime = eachEvent.ReceiveTime.ToString(),
EventOriginTime = eachEvent.OriginTime.ToString(),
CardNumber = eachEvent.CredentialIdentifier)).ToList();
You could add a constructor to the Event class:
public Event(string EventOriginTime, string EventReceivedTime, int EventCode, string CardNumber, string ReaderName)
{
this.EventOriginTime = EventOriginTime;
this.EventReceivedTime = EventReceivedTime;
this.EventCode = EventCode;
this.CardNumber = CardNumber;
this.ReaderName = ReaderName;
}
Then at least you don't have to specify the field names when creating a new instance.
List<Event> listOfEvents = new List<Event>();
foreach (var eachEvent in eventsFromArgus)
{
listOfEvents.Add(new Event(eachEvent.OriginTime.ToString(), eachEvent.ReceiveTime.ToString(), eachEvent.EventCode, eachEvent.DeviceName)
}