C# - Adding data to list inside list - c#

How can I add the following data on the table into a list called Vehicles?
public class criterias
{
public double values { get; set; }
public double time { get; set; }
}
public class movChannels
{
public string name { get; set; }
public IList<criterias> criteria = new List<criterias>();
}
public class stepsList
{
public string steps { get; set; }
public IList<movChannels> stepChannelsCriteria = new List<movChannels>();
}
public class vehicles
{
public int vehID { get; set; }
public string vehDescription { get; set; }
public IList<stepsList> vehValCriteria = new List<stepsList>();
}
Now, how can I add the data that I have in the table shown into a list called Vehicles? I will create other vehicles later...

You had several bad decisions, some were design flaws and some were minor C# naming convention violations.
Couple of worth mentions flaws:
vehID should have been a string and not int (Example "XPT")
Movment has Name, Value and Time. It doesn't have a list of Values and Times.
Creation:
List<Vehicle> vehicles = new List<Vehicle>();
Vehicle vehicle = new Vehicle()
{
Id = "XPT",
Description = "Average Car",
Steps = new List<Step>()
{
new Step() {
Name = "move car",
Movements = new List<Movement>()
{
new Movement("engage 1st gear", 1, 1),
new Movement("reach 10kph", 10, 5),
new Movement("maintain 10kph", 10, 12),
}
},
new Step() {
Name = "stop car",
Movements = new List<Movement>()
{
new Movement("reach 0kph", 10, 4),
new Movement("put in neutral", 0, 1),
new Movement("turn off vehicle", 0, 0),
}
}
}
};
vehicles.Add(vehicle);
Entities:
public class Movement
{
public string Name { get; set; }
public double Values { get; private set; }
public double Time { get; private set; }
public Movement(string name, double values, double time)
{
Name = name;
Values = values;
Time = time;
}
}
public class Step
{
public string Name { get; set; }
public IList<Movement> Movements { get; set; }
}
public class Vehicle
{
public string Id { get; set; } // Should be changed to string
public string Description { get; set; }
public IList<Step> Steps { get; set; }
}

You should create your classes like the following:
public class criterias
{
public double values { get; set; }
public double time { get; set; }
}
public class movChannels
{
public movChannels
{
criteria = new List<criterias>();
}
public string name { get; set; }
public IList<criterias> criteria { get; set; }
}
public class stepsList
{
public stepsList
{
stepChannelsCriteria = new List<movChannels>();
}
public string steps { get; set; }
public IList<movChannels> stepChannelsCriteria { get; set; }
}
public class vehicles
{
public vehicles
{
vehValCriteria = new List<stepsList>();
}
public int vehID { get; set; }
public string vehDescription { get; set; }
public IList<stepsList> vehValCriteria { get; set; }
public movChannels movments { get; set; }
}

What about that?
public class VehiclesViewModel
{
public List<vehicles> Vehicles { get; private set; }
public void Initalize()
{
this.Vehicles = new List<vehicles>();
var vehicle = new vehicles
{
vehID = 1,
vehDescription = "firstDescription",
};
var stepsList = new stepsList
{
steps = "firstStep",
};
var movChannel = new movChannels
{
name = "firstChannel",
};
var criteria = new criterias
{
values = 0.5,
time = 0.5
};
movChannel.criteria.Add(criteria);
stepsList.stepChannelsCriteria.Add(movChannel);
vehicle.vehValCriteria.Add(stepsList);
this.Vehicles.Add(vehicle);
}
}

it seems in your table the VehicleId is of type string. Make sure your VehicleId property in Vehicle class also matches the same.
You can use the collection initializers to set the values of child objects like this way:
var data = new vehicles()
{
vehID = 1,
vehDescription = "Average Car",
vehValCriteria = new List<stepsList>()
{
new stepsList()
{
steps = "Move car",
stepChannelsCriteria = new List<movChannels>()
{
new movChannels()
{
name = "engage firstgear",
criteria = new List<criterias>()
{
new criterias()
{
values = 1,
time = 1
},
}
},
new movChannels()
{
name = "reach 10kph",
criteria = new List<criterias>()
{
new criterias()
{
values = 10,
time = 5
},
}
},
new movChannels()
{
name = "maintain 10kph",
criteria = new List<criterias>()
{
new criterias()
{
values = 10,
time = 12
},
}
}
}
},
new stepsList()
{
steps = "stop car",
stepChannelsCriteria = new List<movChannels>()
{
new movChannels()
{
name = "reach okph",
criteria = new List<criterias>()
{
new criterias()
{
values = 10,
time = 4
},
}
},
new movChannels()
{
name = "put in neutral",
criteria = new List<criterias>()
{
new criterias()
{
values = 0,
time = 1
},
}
},
new movChannels()
{
name = "turn off vehicle",
criteria = new List<criterias>()
{
new criterias()
{
values = 0,
time = 0
},
}
}
}
}
}
};

You can fill your list by moving from top to bottom, like
Create Criterias List then Create movChannel object and add that list
to Criterias object and so on
However if you want to avoid this way, there is another way. If you are using Linq To List then follow this
Get a simple flat object to a list object
var TableData = db.Tablename.Tolist();
Then fill your own object like this
Vehicles finalList = TableData.Select(a => new Vehicles()
{
vehID = a.Id,
vehDescription = a.des,
vehValCriteria = TableData.Where(b => b.StepslistId == a.StepslistId)
.Select(c => new StepsList()
{
steps = c.Steps,
stepChannelsCriteria = TableData.Where(d => d.channelId == c.channelId)
.select(e => new MovChannels()
{
name = e.name,
criteria = TableData.Where(f => f.criteriasId = e.criteriasId)
.Select(g => new Criterias()
{
values = g.Values,
time = g.Time
}).ToList()
}).ToList()
}).ToList()
}).ToList();
This is standard way to fill list within list

Related

Filter data from 2 lists with diferent models C#

I have this models
public class RoutingAttributeModel
{
public int Bus_No { get; set; }
public int Attribute_No { get; set; }
public string Attribute_Name { get; set; }
public string Status { get; set; }
public string Notes { get; set; }
}
public class AgentRoutingAttributeModel
{
public int Agent_No { get; set; }
public int Bus_No { get; set; }
public int Attribute_No { get; set; }
public string Attribute_Name { get; set; }
public string Status { get; set; }
}
List<RoutingAttributeModel> lstComplete = new List<RoutingAttributeModel>();
List<AgentRoutingAttributeModel> lstAssigned = new List<AgentRoutingAttributeModel>();
Filled this with some data
Is it possible to filter with Linq? I want to save in a new list the diferent content between lstComplete and lstAssigned
I was trying to join both lists but got stuck there
var results1 = from cl in lstComplete
join al in lstAssigned
on cl.Attribute_No equals al.Attribute_No
select cl;
you can use linq
as my understanding, you try to find linked by attribute_No records and have a list of not matching properties?
lstComplete.Add(new RoutingAttributeModel(){
Attribute_Name = "aaa",
Attribute_No = 1,
Bus_No = 1,
Notes = "",
Status = "status"
});
lstAssigned.Add(new AgentRoutingAttributeModel()
{
Attribute_No = 1,
Agent_No = 10,
Bus_No = 1,
Attribute_Name = "bbb",
Status = "status2"
});
var lst = lstComplete
.Join(lstAssigned,
complete => complete.Attribute_No,
assigned => assigned.Attribute_No,
(complete, assigned) => new { lstComplete = complete, lstAssigned = assigned })
.Select(s => new { s.lstComplete, s.lstAssigned})
.Where(w=>
w.lstAssigned.Attribute_Name != w.lstComplete.Attribute_Name
|| w.lstAssigned.Bus_No != w.lstComplete.Bus_No
)
.ToList()
.Dump();
so result would be
You could try the following query
var filteredList = lstComplete
.Where(x => !lstAssigned.Any(y => y.Attribute_No == x.Attribute_No));

Linq GroupJoin select query

I have the following model (comments define fields within given object)
public class ServiceModel
{
public List<ShippingRequest> ShippingRequest { get; set; }
public QuotesResult QuotesResult { get; set; }
}
public class ShippingRequest
{
public Address Address { get; private set; } // AddressId
public List<ShippingPackage> ShippingPackages { get; private set; }
}
public class ShippingPackage
{
public Package Package { get; private set; } // PackageId
public List<ShippingItem> ShippingItems { get; private set; } // IsSkipped
}
public class QuotesResult
{
public List<Quote> Quotes { get; set; } // PackageId, Cost
}
Suppose I have the following input, I need to get a list of AddressId's and corresponding Quotes that refer to that address (via PackageId). Quotes are already populated at this point.
Quote.PackageId = Package.PackageId
INPUT:
Suppose I have following input with three ShippingRequests
Address1 = {Package1, Package2, Package3}
Address2 = {Package5, Package8}
Address3 = {Package11, Package12}
To get the all the quotes for a given address I need to Join PackageId of "Package" with PackageId of Quote. That way I will know that this Quote belongs to this Address.
I've tried this but i get an error:
var addrQuotes = ServiceModel.ShippingRequest
.GroupJoin(ServiceModel.QuotesResult.Quotes, c1 => c1.ShippingPackages
.SelectMany(y => y.Package.Id), c2 => c2.PackageId, (c1, c2) =>
new {
c1.Address.Id,
Quotes = c2.Select(e =>
{
e.Price = c1.ShippingPackages.Any(
x => x.ShippingItems.All(y => y.IsSkipped))
? 0
: e.Price + ExtraCost;
e.Provider = GetName(e.Code);
return e;
})
}).OrderBy(q => q.Id);
One caviar to this is that I also need to check ShippingItems(s) that go in a Package. If ALL the ShippingItems within a ShippingPackage have boolean flag "IsSkipped" set to true, the Quote's Price should be set to 0, otherwise add Extra cost to Quote.Price.
OUTPUT:
Address1 = [Quote1, Quote20, Quote21, Quote50, ...]
Address2 = [Quote3, Quote100...]
Address3 = [Quote5, Quote33, Quote12]
Any help greatly appreciated.
I didn't do entire job but got something to compile and run without errors. This should get you pointed in right direction.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
ServiceModel serviceModel = new ServiceModel()
{
ShippingRequest = new List<ShippingRequest>(){
new ShippingRequest() {
Address = "Address 1",
ShippingPackages = new List<ShippingPackage>() {
new ShippingPackage() { Package = "Package1"},
new ShippingPackage() { Package = "Package2"},
new ShippingPackage() { Package = "Package3"}
}
},
new ShippingRequest() {
Address = "Address 2",
ShippingPackages = new List<ShippingPackage>() {
new ShippingPackage() { Package = "Package5"},
new ShippingPackage() { Package = "Package8"},
}
},
new ShippingRequest() {
Address = "Address 3",
ShippingPackages = new List<ShippingPackage>() {
new ShippingPackage() { Package = "Package11"},
new ShippingPackage() { Package = "Package12"},
}
}
},
QuotesResult = new QuotesResult()
{
Quotes = new List<Quote>() {
new Quote() { Cost = 123, Id = "Package1"},
new Quote() { Cost = 123, Id = "Package2"},
new Quote() { Cost = 123, Id = "Package3"},
new Quote() { Cost = 123, Id = "Package11"},
new Quote() { Cost = 123, Id = "Package11"}
}
}
};
var addrQuotes = (from requests in serviceModel.ShippingRequest.Select(x => x.ShippingPackages.Select(y => new { address = x.Address, package = y})).SelectMany(z => z)
join quote in serviceModel.QuotesResult.Quotes
on requests.package.Package equals quote.Id
select new { quote = quote, package = requests }).ToList();
var results = addrQuotes.GroupBy(m => m.package.address)
.Select(n => new {
quotes = n.Select(c => c).Select(c1 => new {
address = c1.package.address,
quote = c1.quote
}).ToList()
}).ToList();
}
}
public class ServiceModel
{
public List<ShippingRequest> ShippingRequest { get; set; }
public QuotesResult QuotesResult { get; set; }
}
public class ShippingRequest
{
public string Address { get; set; } // AddressId
public List<ShippingPackage> ShippingPackages { get; set; }
}
public class ShippingPackage
{
public string Package { get; set; } // PackageId
public List<string> ShippingItems { get; set; } // IsSkipped
}
public class QuotesResult
{
public List<Quote> Quotes { get; set; } // PackageId, Cost
}
public class Quote
{
public string Id { get; set; }
public decimal Cost { get; set; }
}
}

How to use condition for all children in Entity Framework

I have these classes:
public class product
{
public int Id { get; set; }
public string Title { get; set; }
public Store Store { get; set; }
public ICollection<Color> Colors { get; set; }
}
public class Color
{
public int Id { get; set; }
public string Name { get; set; }
public product Product { get; set; }
}
public class Store
{
public int Id { get; set; }
public string Name { get; set; }
public string City { get; set; }
public ICollection<product> Products { get; set; }
}
And I have this list :
List<Store> Stores = new List<Store>
{
new Store { Id = 1, Name = "Lilo", City = "Teh",
Products = new List<product>
{
new product
{ Id = 1, Title = "Asus",
Colors = new List<Color> {
new Color { Id = 1, Name = "Blue"},
new Color { Id = 2, Name = "Orange"}
}
},
new product
{ Id = 2, Title = "Dell",
Colors = new List<Color> {
new Color { Id = 1, Name = "Yellow"},
new Color { Id = 2, Name = "Orange"},
new Color { Id = 3, Name = "Red"}
}
}
}
},
new Store{Id=2,Name="filo",City="san",
Products=new List<product>
{
new product{Id=3,Title="Asus",
Colors=new List<Color>{
new Color{Id=1,Name="Blue"},
new Color{Id=2,Name="Orange"}
}
},
new product{Id=4,Title="Dell",
Colors=new List<Color>{
new Color{Id=1,Name="Yellow"},
new Color{Id=2,Name="Lime"},
new Color{Id=3,Name="Red"}
}
}
}
}
};
I want to select all stores where Name ="Lilo" and products names is "Dell " and Color="Blue". I want do this in Entity Framework, not Linq.
I use this code but it doesn't work :
var test = Stores.Where(s => s.Name = "lilo" && s.Products.Where(p => p.Title == "Dell").FirstOrDefault().Title == "Dell" && s.Products.Where(c => c.Colors.Where(ct => ct.Name == "Blue").FirstOrDefault().Name = "Blue")).ToList();
How can I do this ?
Do this By Method Syntax :
var stlist = Stores.Where(s => s.Name.ToLower() == "lilo" && s.Products.Where(p => p.Colors.Any(c=>c.Name=="Blue") && p.Title == "Dell").FirstOrDefault().Title == "Dell").ToList();
Updated :
And Hopeless's Answers is (best answers):
var lslist2= Stores.Where(s => s.Name == "lilo" && s.Products.Any(p => p.Title == "Dell" && p.Colors.Any(c => c.Color.Name == "Blue"))).ToList();
And by Linq :
var test = (from s in Stores
from p in s.Products
from c in p.Colors
where s.Name=="Lilo" && p.Title=="Dell"&& c.Name=="Blue"
select s
).ToList();

Seed list inside an empty list

I'm working with KnockoutMVC and it requires strongly type models to use inside the VIEW. I have tried multiple variations of the examples on KnockoutMVC's site including using ENUMS and still could not get it to work. Perhaps this is a problem with the setup of my models.
MODELS
public class PhoneNumber
{
public List<NumberTypeClass> Types { get; set; }
//public NumberType enumType { get; set; }
//public enum NumberType
//{
// Work,
// Home,
// Mobile,
// Fax
//}
private string _number;
[StringLength(14, MinimumLength = 10, ErrorMessage = "Please use (123) 456-7890 format"), Required]
public string Number
{
get
{
this._number = BeautifyPhoneNumber(this._number);
return this._number;
}
set
{
this._number = value;
}
}
public string Extension { get; set; }
public static String BeautifyPhoneNumber(string numberToBeautify)
{
//beautifyNumberCode
}
}
public class NumberTypeClass
{
public int Id { get; set; }
public string NumberType { get; set; }
}
public class VendorsEditorVendorModel
{
public string FirstName {Get;set;}
public string LastName {get;set;}
public List<Address> Address {get;set;}
public List<PhoneNumber> Phones {get;set;}
}
public class VendorsEditorModel
{
public List<VendorsEditorVendorModel> Vendors {get;set;}
}
CONTROLLER
public class VendorsEditorController : BaseController
{
public ActionResult CreateVendors()
{// VendorsEditor/CreateVendors
var vendor = new VendorsEditorModel();
vendor.Vendors = new List<VendorsEditorVendorModel>();
vendor.Vendors[0].Phones[0].Types = new List<NumberTypeClass>
{
new NumberTypeClass{Id = 0, TypeName = "Mobile"},
new NumberTypeClass{Id = 0, TypeName = "Work"},
new NumberTypeClass{Id = 0, TypeName = "Home"}
};//this throws an error because there is no Vendors[0] ...but how would i populate this list for every Vendor?
return View(vendor);
}
}
You cannot call an empty collection by index [x]. You need to fill your collection from a database or what not before you can access items in it. If you are just trying to add items to a collection, this is how you do it:
var vendor = new VendorsEditorModel
{
Vendors = new List<VendorsEditorVendorModel>
{
new VendorsEditorVendorModel
{
Phones = new List<PhoneNumber>
{
new PhoneNumber
{
Types = new List<NumberTypeClass>
{
new NumberTypeClass {Id = 0, NumberType = "Mobile"}
}
}
}
}
}
};
If you just want to add the types to an already populated collection, you can do the following:
foreach (var phone in vendor.Vendors.SelectMany(item => item.Phones))
{
phone.Types = new List<NumberTypeClass>
{
new NumberTypeClass{Id = 0, NumberType = "Mobile"},
new NumberTypeClass{Id = 0, NumberType = "Work"},
new NumberTypeClass{Id = 0, NumberType = "Home"}
};
}

Issue getting required output using LINQ query

I need to get data as per this json format.
series: [{
name: 'Marriage',
data: [1, 2, 3] // Sample Data
}, {
name: 'Chess',
data: [2, 2, 3]
}, {
name: 'Ludo',
data: [3, 4, 4]
}]
I need to create chart as here in http://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/demo/bar-stacked/
What I have tried is using group by from device id and and using for loop to get the result. But I am quite stuck here getting required output.
Here is what I have tried so far.
void Main()
{
DateTime currentDate = DateTime.UtcNow.Date.AddDays(-30);
var currentMonthData = Device_GameDevices.Where(x => x.CreatedDate >= currentDate).ToList();
// Get total game list
var gamesList = currentMonthData.Select(x => x.GameName).Distinct();
// Group the data as per the device id
var groupedData = from gameData in currentMonthData
group gameData by gameData.DeviceID
into egroup
select new {
Game = egroup.Key,
Data = from bug in egroup
group bug by bug.GameName into g2
select new { Name = g2.Key, HoursPlayed = g2.Sum(x => (x.EndTime - x.StartTime).TotalMinutes/60) }
};
Console.Write(groupedData);
List<DashboardVM.ChartData> chartDatas = new List<DashboardVM.ChartData>();
List<double> hourResultList = new List<double>();
foreach(var item in groupedData)
{
var chart = new DashboardVM.ChartData();
foreach(var gameItem in gamesList)
{
chart.GameNameResult = gameItem;
foreach(var groupedDataItem in item.Data)
{
if(gameItem == groupedDataItem.Name)
{
hourResultList.Add(groupedDataItem.HoursPlayed);
}
else
{
hourResultList.Add(0.0);
}
}
chart.HoursPlayed = hourResultList;
}
chartDatas.Add(chart);
}
Console.Write(chartDatas);
}
public class DashboardVM{
public class ChartData{
public string GameNameResult{get;set;}
public List<double> HoursPlayed{get;set;}
}
}
public class Chart
{
public string type { get; set; }
}
public class Title
{
public string text { get; set; }
}
public class XAxis
{
public List<string> categories { get; set; }
}
public class Title2
{
public string text { get; set; }
}
public class YAxis
{
public int min { get; set; }
public Title2 title { get; set; }
}
public class Legend
{
public bool reversed { get; set; }
}
public class Series
{
public string stacking { get; set; }
}
public class PlotOptions
{
public Series series { get; set; }
}
public class Series2
{
public string name { get; set; }
public List<double> data { get; set; }
}
public class RootObject
{
public Chart chart { get; set; }
public Title title { get; set; }
public XAxis xAxis { get; set; }
public YAxis yAxis { get; set; }
public Legend legend { get; set; }
public PlotOptions plotOptions { get; set; }
public List<Series2> series { get; set; }
}
void Main()
{
var Device_GameDevices = new[] {
new {ID=1,CreatedDate=DateTime.Parse("8/23/2017 06:07:30"),DeviceID="Desktop12",EndTime=DateTime.Parse("8/23/2017 06:06:30"),GameName="CyberGunner",StartTime=DateTime.Parse("8/23/2017 06:03:45")},
new {ID=2,CreatedDate=DateTime.Parse("8/23/2017 07:14:01"),DeviceID="A12" ,EndTime=DateTime.Parse("8/23/2017 11:14:01"),GameName="Marriage" ,StartTime=DateTime.Parse("8/23/2017 07:14:01")},
new {ID=3,CreatedDate=DateTime.Parse("8/23/2017 07:14:02"),DeviceID="A12" ,EndTime=DateTime.Parse("8/23/2017 08:14:01"),GameName="Marriage" ,StartTime=DateTime.Parse("8/23/2017 07:14:02")},
new {ID=4,CreatedDate=DateTime.Parse("8/23/2017 09:14:01"),DeviceID="A12" ,EndTime=DateTime.Parse("8/23/2017 09:14:01"),GameName="Chess" ,StartTime=DateTime.Parse("8/23/2017 07:14:03")},
new {ID=5,CreatedDate=DateTime.Parse("8/23/2017 07:14:03"),DeviceID="A12" ,EndTime=DateTime.Parse("8/23/2017 10:14:01"),GameName="Marriage" ,StartTime=DateTime.Parse("8/23/2017 07:14:03")},
new {ID=6,CreatedDate=DateTime.Parse("8/23/2017 09:57:28"),DeviceID="B12" ,EndTime=DateTime.Parse("8/23/2017 10:57:28"),GameName="Marriage" ,StartTime=DateTime.Parse("8/23/2017 09:57:28")},
};
DateTime currentDate=DateTime.UtcNow.Date.AddDays(-30);
var currentMonthData=Device_GameDevices
.Where(x=>x.CreatedDate>=currentDate)
.ToList();
// Get total game list
var gamesList=currentMonthData
.Select(x=>x.GameName)
.Distinct()
.ToList();
var chart=new RootObject
{
chart=new Chart{ type="bar"},
title=new Title{ text="My title" },
xAxis=new XAxis { categories=gamesList },
yAxis=new YAxis { min=0, title=new Title2 {text="Total Game Time"}},
legend=new Legend {reversed=true},
plotOptions=new PlotOptions { series=new Series {stacking="normal"}},
series=currentMonthData
.GroupBy(d=>new {d.DeviceID,d.GameName})
.Select(d=>new {
DeviceID=d.Key.DeviceID,
GameName=d.Key.GameName,
HoursPlayed=d.Sum(x=>(x.EndTime - x.StartTime).TotalMinutes)/60
})
.GroupBy(d=>d.DeviceID)
.Select(d=>new Series2 {
name=d.Key,
data=gamesList
.GroupJoin(d,a=>a,b=>b.GameName,(a,b)=>new {GameName=a,HoursPlayed=b.Sum(z=>z.HoursPlayed)})
.OrderBy(x=>gamesList.IndexOf(x.GameName))
.Select(x=>x.HoursPlayed)
.ToList()
}).ToList()
};
chart.Dump();
}
This is how the series looks:

Categories