Accessing element of a List. C# - c#

I have created a List of type Students. The following classes are the ones I use;
public class StudentDetails
{
public class Address
{
public int HouseNumber{ get; set; }
public string LineOne{ get; set; }
public string LineTwo{ get; set; }
}
public class Student
{
public int StudentId { get; set; }
public Address StudentAddress{ get; set; }
}
public List<Student> GetStudents()
{
private Address StudentOne = new Address{//details};
private Address StudentTwo = new Address{//details};
var students = new List<Student>();
students.add(new Student {StudentId = 1, StudentAdress = StudentOne, //details});
//more students
return students;
}
}
Now I would like to access certain details of a particular student from this object. Say I want to get the House number of a student. How can i do that? I attempted to create another list, then add the list returned from GetStudents(). However when i iterate through it , i only get references to objects.
//To access the List
StudentDetails student = new StudentDetails(); //create new instance
for (int i = 0; i < student.GetStudents().Count; i++)
{
//Console.WriteLine(student[1].GetStudents());
}

You can use Linq to select the student you are searching for and then access its properties:
var student = GetStudents().FirstOrDefault(student => student.StudentId /* your student id here */>);
if (student != null)
{
var houseNumber = student.Address.HouseNumber;
}

Try this
StudentDetails student = new StudentDetails(); //create new instance
foreach (var s in student.GetStudents())
{
var id = s.StudentId;//use any properties using . operator
Console.WriteLine(s);
}

Console.WriteLine(GetStudents()[0].HouseNumber.ToString());
(0 can be whatever number)
or (gets a list of students and their house numbers) :
var houseNumbers = GetStudents().Select((student) =>
String.Format("Student: {0} - {1}",
student.StudentId, student.Address.HouseNumber));
foreach(var entry in houseNumbers) Console.WriteLine(entry);

Related

LiveCharts2 populating chart with Entity Framework

I'm starting with Livecharts2 (I did not try previous versions) and I'm not sure how to bind data with Entity Framework.
I need to display a chart with warehouse name and the quantity of access of each.
This is what I already have:
List<Access> access = context.Access.ToList();
var countAccess = access
.GroupBy(acc => acc.IdWarehouse)
.Select(group => new
{
Warehouse = group.Key,
Quantity = group.Count()
});
List<int> listQt = new List<int>();
List<int> list_warehouses = new();
foreach (var item in countAccess)
{
listQt.Add(item.Quantity);
list_warehouses.Add(item.Warehouse);
}
cartesianChart1.Series = new ISeries[]
{
new LineSeries<int>
{
Values = listQt,
Name = "Quantity"
},
new ColumnSeries<int>
{
Values = list_warehouses,
Name = "Warehouse"
}
};
My model classes:
public partial class Access
{
public int IdAccess { get; set; }
public byte IdWarehouse { get; set; }
}
public partial class Warehouse
{
public byte IdWarehouse { get; set; }
public string Name{ get; set; } = null!;
}
This code works with the IdWarehouse but Name, is there a better way to do it, instead of creating new list, foreach etc? I'm not sure if it is unnecessary
I tried with List<string> to get the warehouse's names, but got an exception cause is not implemented yet by creator/s

How to create list with Ids representing index of each record(like associative array )?

I have a json structure like this:
public class MyModel
{
public int Id { get; set; }
public List<Tables> Tables { get; set; }
}
public class Tables
{
public string Name { get; set; }
public string[] Columns { get; set; }
}
This is how I am creating this structure:
var Ids = new List<int>();
Ids.Add(100);
Ids.Add(101);
Ids.Add(102);
var list = new List<MyModel>();
foreach (var item in Ids)
{
list.Add(
new MyModel
{
Id = item,
Tables = GetTables()
}
);
}
public List<Tables> GetTables()
{
from table in connection.GetSchema("Tables").AsEnumerable()
let name = (string)table["TABLE_NAME"]
let catalog = (string)table["TABLE_CATALOG"]
let schema = (string)table["TABLE_SCHEMA"]
select new Tables
Name = name,
Columns =
from column in connection.GetSchema("Columns", new [] { catalog, schema, name }).AsEnumerable()
select (string)column["COLUMN_NAME"]).ToArray()
}).ToList();
It is possible to have data like this :
[101] : List of tables
[102] : List of tables
[103] : List of tables
Right now i am doing this on client side(ie in javascript) like below:
var list = [];
for (var i = 0; i < response.length; i++) {
list[response.Id] = { tables: response[i].tables };
}
So can i create same response like above on server side?
You can create using Dictionary.
public class RootObject
{
public Dictionary<int, List<Tables>> MyModel { get; set; }
}
You have to pass id as a key and list of tables as a value.
You can use hash table.after getting your data for list variable.then looping the your list variable and add to hash table.
Hashtable hashtable = new Hashtable();
foreach (MyModel myItem in yourlistvariable)
{
if (!hashtable.ContainsKey(myItem.Id))
{
hashtable[myItem.Id] = myItem.Tables;
}
}
finally in hashtable variable you have data how you want

How to create a dictionary of field values/counts from an observable collection?

I have an ObservableCollection<CustomerModel> Customers, that holds a Country field. What I want to do is, create an observable collection of type PiePointModel. In order to store the country name and number of occurrences of that country name.
So I set up an ObservableCollection<PiePointModel> CountryRatioCollection, where PiePoint holds a name and amount.
Then I tried to assign that collection to my Customers, by converting it to a dictionary holding the required values:
CountryRatioCollection = new ObservableCollection<PiePointModel>();
CountryRatioCollection = Customers.GroupBy(i => i.Country).ToDictionary(g => g.Key, g => g.Count());
But I get an error stating that this can't be implicitly converted:
Error 2 Cannot implicitly convert type 'System.Collections.Generic.Dictionary<string,int>' to 'System.Collections.ObjectModel.ObservableCollection<MongoDBApp.Models.PiePointModel>'
I understand that this is because the Dictionary type is not the same as my PiePoint model class.
Can anyone offer advice on making query and conversion?
This is the PiePoint class for reference, that holds the name and amount:
public class PiePointModel
{
public string Name { get; set; }
public int Amount { get; set; }
}
And this is the CustomerModel that holds the country field:
public class CustomerModel
{
[BsonId]
public ObjectId Id { get; set; }
[BsonElement("firstName")]
public string FirstName { get; set; }
[BsonElement("lastName")]
public string LastName { get; set; }
[BsonElement("email")]
public string Email { get; set; }
[BsonElement("address")]
public string Address { get; set; }
[BsonElement("country")]
public string Country { get; set; }
public override string ToString()
{
return Country;
}
}
You should use Select (not ToDictionary) and create PiePointModel for each group.
IEnumerable<PiePointModel> piePoints = Customers.GroupBy(i => i.Country).Select(s => new PiePointModel()
{
Name = s.Key,
Amount = s.Count()
});
CountryRatioCollection = new ObservableCollection<PiePointModel>(piePoints);
Also notice that I used: CountryRatioCollection = new ObservableCollection<PiePointModel>(..) because CountryRatioCollection is of type ObservableCollection and you cannot assign here dictionary like in your example.
Constructor of ObservableCollection<T> can take IEnumerable<T> - I used it here.
Other way is use loop and add new PiePointModel to collection
CountryRatioCollection = new ObservableCollection<PiePointModel>();
var groups = Customers.GroupBy(i => i.Country);
foreach(var gr in groups)
{
PiePointModel piePointModel = new PiePointModel()
{
Name = gr.Key,
Amount = gr.Count()
};
CountryRatioCollection.Add(piePointModel);
}

Filling class object from multiple dataset

I want to fill the Organism class object with data from OrganismDT and AntibioticDT. below are the Datatable structure,Class structure and the filling technique i am trying. based on the OrganismAliasId i have to fill the AntibioticsDT[Antibiotic objects list] rows and assign to corresponding Organisms object. Could any one please help me to achieve this..
DataTable
DataTable OrganismDT = new DataTable("Organism");
OrganismDT.Columns.Add("OrganismAliasId");
OrganismDT.Columns.Add("Name");
DataTable AntibioticsDT = new DataTable("Antibiotics");
AntibioticsDT.Columns.Add("OrganismAliasId");
AntibioticsDT.Columns.Add("Name");
AntibioticsDT.Columns.Add("Susceptibility");
Class Structure:
public class Organism
{
public int AliasId { get; set; }
public string Name { get; set; }
public List<Antibiotic> Antibiotics;
}
public class Antibiotic
{
public string Name { get; set; }
public string Susceptibility { get; set; }
}
filling Datatable table to Class object
List<Organism> Organisms = Organism.AsEnumerable().Select(row =>
new Organism
{
AliasId = row.Field<int>("OrganismAliasId"),
Name = row.Field<string>("Name"),
Antibiotics = new List<Antibiotic>()
}).ToList();
This should work:-
List<Organism> Organisms = OrganismDT.AsEnumerable().Select(row =>
new Organism
{
AliasId = row.Field<int>("OrganismAliasId"),
Name = row.Field<string>("Name"),
Antibiotics = AntibioticsDT.AsEnumerable()
.Where(x => x.Field<int>("OrganismAliasId")
== row.Field<int>("OrganismAliasId"))
.Select(x => new Antibiotic
{
Name = x.Field<string>("Name"),
Susceptibility = x.Field<string>("Susceptibility")
}).ToList()
}).ToList();
Also, Please note you should create the columns by specifying their datatypes otherwise it may throw run-time exception:-
AntibioticsDT.Columns.Add("OrganismAliasId",typeof(int));

How do I access the <List> inside another <List>?

I'm having a tough time figureing out how to use the ForEach (or not use it) to print out the Car list I have inside the Parent list. I know obviously I can't do XmlData.p.b.ForEach and that the code below is just an example, as I'm going to have to do a lot of manipulation, but I just need to know how I can access the list in b inside the list p.
public static void Main(string[] args)
{
XmlSerializer deserializer = new XmlSerializer(typeof(Address));
TextReader reader = new StreamReader("myXML.xml");
object obj = deserializer.Deserialize(reader);
Address XmlData = (Address)obj;
reader.Close();
XmlData.p.ForEach(p => Console.WriteLine("Item in p!");
XmlData.p.b.ForEach(b => Console.WriteLine("Item in b!"); // can't do this
}
XML Format:
Top: MyRoot
----------Target
-----------------Parent
----------------------------Cars
[XmlRoot("MyRoot")]
public class MyRoot
{
[XmlElement("Dealership")]
public String dealership;
[XmlElement("ZipCode")]
public String zipCode;
[XmlArray("Targets")]
[XmlArrayItem("Parent")]
public List<Parent> p = new List<Parent>();
}
public class Parent : Student
{
[XmlElement("ParentName")]
public String parentName { get; set; }
}
public class Student
{
[XmlElement("Owner")]
public String owner { get; set; }
[XmlElement("Age")]
public String age { get; set; }
[XmlElement("Name")]
[XmlArrayItem("Cars")]
public List<Cars> c = new List<Cars>();
}
public class Cars
{
[XmlElement(Namespace="BuildDependency/CarYear")]
public String carYear { get; set; }
[XmlElement(Namespace = "BuildDependency/CarMake")]
public String carMake { get; set; }
[XmlElement(Namespace = "BuildDependency/CarModel")]
public String carModel { get; set; }
[XmlElement("CarColor")]
public String carColor { get; set; }
[XmlElement("CarMileage")]
public String carMileage { get; set; }
}
You could flatten the list using SelectMany:
XmlData.p.SelectMany(p => p.b).ToList()
.ForEach(b => Console.WriteLine("Item in b!"));
If you wish to iterate a list that is inside another list easy, you can do it within the first list iteration scope, something like (not gonna use lambda expressions but standard loops to keep it simple):
for(int i=0; i<XmlData.p.Length; i++) {
Console.WriteLine("Item in a!");
for(j=0; j<XmlData.p[i].b.Length; j++) {
Console.WriteLine("Item in b!");
}
}
Or you can just nest the second ForEach call:
XmlData.p.ForEach(outer => outer.b.ForEach(inner => Console.WriteLine("Item in b!")));
It's quite obvious that this doens't work, your code needs to be adapted so the b come's into the foreach class.
Your 2 nd call (iterating over list in list) should be:
XmlData.p.ForEach(p => p.c.ForEach(c => { Console.WriteLine("Item in C"); }));
I've written a very small demo project that I will share:
First some classes to make the project work:
public class MyRoot
{
public List<Student> p = new List<Student>();
}
public class Student
{
public List<Cars> c = new List<Cars>();
}
public class Cars
{
public String carYear { get; set; }
public String carMake { get; set; }
public String carModel { get; set; }
public String carColor { get; set; }
public String carMileage { get; set; }
}
Then the initiazization:
var cars = new List<Cars>();
cars.Add(new Cars());
cars.Add(new Cars());
cars.Add(new Cars());
cars.Add(new Cars());
var student = new List<Student>();
student.Add(new Student() { c = cars });
var root = new MyRoot();
root.p = student;
So we create 4 cars and 1 student with the 4 cars.
In the root object we set the list of students to just 1 student with the 4 cars.
So we have the following situation:
-- Root
-- Student
-- Car
-- Car
-- Car
-- Car
Now, to iterate over it, you need to do the following:
root.p.ForEach(p => Console.WriteLine("Item in 1"));
root.p.ForEach(p => p.c.ForEach(c => Console.WriteLine(" Item in 2")));
This will give the output:
Note: When you have 2 students, 1 student with 4 cars and the other one with 2 cars, the output will become:
This is because first we're iterating over the students and then over the cars.
When you see for each student it's cars, you can nest your foreach. Your foreach will then looks like:
root.p.ForEach(p =>
{
Console.WriteLine("Item in 1");
p.c.ForEach(c => Console.WriteLine(" Item in 2"));
});
And then your output will be:
So, fairly long post but I hope it helps.

Categories