c# linq join on a sublist in a list - c#

I have a list: var_assets_root that has a nested sub list: contents. I can do a join on the root list and augment it with extra items from the two other lists lst_invtypes_assets and lst_stations_composite_retribution by doing two joins on index items in var_assets_root. But I also want to do a join on the items that are within the sublist var_assets_root-->contents\b.contents which the code below is not doing so far.
Image>>structure of var_assets_root in watch window
mysql mysql_object = new mysql();
List<mysql.invtypes_asset> lst_invtypes_assets = mysql_object.dbmysql_invtypes_asset_to_list();
List<mysql.stations_composite_retribution> lst_stations_composite_retribution = mysql_object.dbmysql_select_stastations_composite_retribution_to_list();
var lst_assets_list = new AssetList("134399", "343434SxSFX7qO81LqUCberhS1OQtktMvARFGED0ZRSN5c4XP230SA", "434367527");
lst_assets_list.Query();
var var_assets_root = lst_assets_list.assets.ToList();
var var_assets_root_typeid_station
= from b in var_assets_root
join c in lst_invtypes_assets on b.typeID equals c.typeID
join d in lst_stations_composite_retribution on b.locationID equals d.stationID
select new {b.contents, b.flag, b.itemID, b.locationID, d.solarSystemName, d.security, d.securityClass, d.regionName, b.quantity, b.singleton, b.typeID, c.groupID, c.marketGroupID, c.volume,
c.typeName, c.description};
I have done a solution of running a linq query for every content sub list and assigning values accordingly.
private void btn_evenet_Click(object sender, EventArgs e)
{
Stopwatch stopwatch1 = new Stopwatch();
Stopwatch stopwatch2 = new Stopwatch();
stopwatch1.Start();
mysql mysql_object = new mysql();
List<mysql.invtypes_asset> lst_invtypes_assets = mysql_object.dbmysql_invtypes_asset_to_list();
List<mysql.stations_composite_retribution> lst_stations_composite_retribution = mysql_object.dbmysql_select_stastations_composite_retribution_to_list();
AssetList lst_assets_list = new AssetList("2312099", "J&VNM14RFUkSxSFX7qAAAAAA1OQtktMvYTVZZBhkO23235c4Z&HJKODPQLM", "123231527");
lst_assets_list.Query();
var var_assets_root = lst_assets_list.assets.ToList();
var var_assets_root_typeid_station
= from b in var_assets_root
join c in lst_invtypes_assets on b.typeID equals c.typeID
join d in lst_stations_composite_retribution on b.locationID equals d.stationID
select new { b.contents, b.flag, b.itemID, b.locationID, d.solarSystemName, d.security, d.securityClass, d.regionName, b.quantity, b.singleton, b.typeID, c.groupID, c.marketGroupID, c.volume,
c.typeName, c.description};
var lst_assets_root_typeid_station = var_assets_root_typeid_station.ToList(); // Using .ToArray() is about 200ms faster than .ToList()
stopwatch2.Start();
for (Int32 a = 0; a < lst_assets_root_typeid_station.Count(); a++)
{
if (lst_assets_root_typeid_station[a].contents.Count() >= 0)
{
for (Int32 b = 0; b < lst_assets_root_typeid_station[a].contents.Count(); b++)
{
var var_row_invtypes_assets = lst_invtypes_assets.Where(x => x.typeID == lst_assets_root_typeid_station[a].contents[b].typeID).ToArray();
lst_assets_root_typeid_station[a].contents[b].groupID = var_row_invtypes_assets[0].groupID;
lst_assets_root_typeid_station[a].contents[b].typeName = var_row_invtypes_assets[0].typeName;
lst_assets_root_typeid_station[a].contents[b].description = var_row_invtypes_assets[0].description;
lst_assets_root_typeid_station[a].contents[b].volume = var_row_invtypes_assets[0].volume;
lst_assets_root_typeid_station[a].contents[b].marketGroupID = var_row_invtypes_assets[0].marketGroupID;
if (lst_assets_root_typeid_station[a].contents[b].contents.Count() != 0)
{
for (Int32 c = 0; c < lst_assets_root_typeid_station[a].contents[b].contents.Count(); c++)
{
var_row_invtypes_assets = lst_invtypes_assets.Where(x => x.typeID == lst_assets_root_typeid_station[a].contents[b].contents[c].typeID).ToArray();
lst_assets_root_typeid_station[a].contents[b].contents[c].groupID = var_row_invtypes_assets[0].groupID;
lst_assets_root_typeid_station[a].contents[b].contents[c].typeName = var_row_invtypes_assets[0].typeName;
lst_assets_root_typeid_station[a].contents[b].contents[c].description = var_row_invtypes_assets[0].description;
lst_assets_root_typeid_station[a].contents[b].contents[c].volume = var_row_invtypes_assets[0].volume;
lst_assets_root_typeid_station[a].contents[b].contents[c].marketGroupID = var_row_invtypes_assets[0].marketGroupID;
}
}
}
}
}
stopwatch2.Stop();
stopwatch1.Stop();
lbl_stopwatch1.Text = "Everything: " + stopwatch1.Elapsed.ToString("mm\\:ss\\.ff"); // 1.53 seconds no debugging
lbl_stopwatch2.Text = "contents sublists: " + stopwatch2.Elapsed.ToString("mm\\:ss\\.ff"); // contents sublists take 1.03 seconds no debugging
}
}
Once I figured that 'yield' pops one content node from a stack of content nodes when getAllContents is called I adapted my code and your function so that now all content nodes get recursed into and have their empty values filled from a linq query. Also the new code that is after the linq creation of var_assets_root_typeid_station is now almost twice as fast. Thank you.
private void btn_evenet_Click(object sender, EventArgs e)
{
Stopwatch stopwatch1 = new Stopwatch();
Stopwatch stopwatch2 = new Stopwatch();
stopwatch1.Start();
mysql mysql_object = new mysql();
List<mysql.invtypes_asset> lst_invtypes_assets = mysql_object.dbmysql_invtypes_asset_to_list();
List<mysql.stations_composite_retribution> lst_stations_composite_retribution = mysql_object.dbmysql_select_stastations_composite_retribution_to_list();
AssetList lst_assets_list = new AssetList("12345678", "ABCDEFFGHIKL01235kokJDSD213123", "12345678");
lst_assets_list.Query();
var var_assets_root = lst_assets_list.assets.ToList();
var var_assets_root_typeid_station
= from b in var_assets_root
join c in lst_invtypes_assets on b.typeID equals c.typeID
join d in lst_stations_composite_retribution on b.locationID equals d.stationID
select new
{b.contents, b.flag, b.itemID, b.locationID, d.solarSystemName, d.security, d.securityClass, d.regionName, b.quantity, b.singleton, b.typeID, c.groupID, c.marketGroupID, c.volume,
c.typeName, c.description};
var lst_assets_root_typeid_station = var_assets_root_typeid_station.ToList(); // Using .ToArray() is about 200ms faster than .ToList()
stopwatch2.Start();
for (Int32 a = 0; a < lst_assets_root_typeid_station.Count(); a++)
{
if (lst_assets_root_typeid_station[a].contents.Count() > 0)
{
for (Int32 z = 0; z < lst_assets_root_typeid_station[a].contents.Count(); z++)
{
foreach (AssetList.Item contentnode in getAllContents(lst_assets_root_typeid_station[a].contents[z]))
{
var var_row_invtypes_assets = lst_invtypes_assets.Where(x => x.typeID == contentnode.typeID).ToArray();
contentnode.groupID = var_row_invtypes_assets[0].groupID;
contentnode.typeName = var_row_invtypes_assets[0].typeName;
contentnode.description = var_row_invtypes_assets[0].description;
contentnode.volume = var_row_invtypes_assets[0].volume;
contentnode.marketGroupID = var_row_invtypes_assets[0].marketGroupID;
}
}
}
}
stopwatch2.Stop();
stopwatch1.Stop();
lbl_stopwatch1.Text = "Everything: " + stopwatch1.Elapsed.ToString("mm\\:ss\\.ff"); // 1.16 seconds no debugging
lbl_stopwatch2.Text = "contents sublists: " + stopwatch2.Elapsed.ToString("mm\\:ss\\.ff"); // contents sublists take 0.63 seconds no debugging
}
IEnumerable<AssetList.Item> getAllContents(AssetList.Item contentNode)
{
if (contentNode.contents.Count == 0)
{
yield return contentNode;
}
else
{
foreach (AssetList.Item subContentNode in contentNode.contents)
{
yield return subContentNode;
foreach (AssetList.Item subSubContentNode in getAllContents(subContentNode))
yield return subSubContentNode;
}
}
}

Aren't you just looking for SelectMany?
var contents = lst_invtypes_assets.contents.SelectMany(x => x.contents);

What I think you're getting at is that you want to access the outer .contents property, and if it contains any contents, then access those, too, and so on... recursively.
While you could do this by defining a recursive Func<AssetList.Item, IEnumerable<AssetList.Item>> and a line of LINQ using .Aggregate, it will probably be easier/more readable to define your own recursive method.
IEnumerable<AssetList.Item> getAllContents(AssetList.Item station) {
foreach (AssetList.Item subStation in station.contents) {
yield return subStation;
foreach (AssetList.Item subSubStation in getAllContents(substation))
yield return subSubStation;
}
}
You can then do a simple foreach(var station in getAllContents(parentStation)), or modify this to include the original station, make it an extension method, etc.

Related

c# cannot convert system.collections.generic.icollection<kmsentities.PMRUnitTypes> to KMSEntities.PMRUnitTypes

I was troubleshooting one of our pages and I found a feachloop that had nested foreach loops in it and instead of nesting them I was going to multithread the foreach loops and break them out individually
List<int> buildings = new List<int>();
List<int> wings = new List<int>();
List<int> complexes = new List<int>();
List<int> unittypes = new List<int>();
int floors = 0;
int unitcnt = 0;
ICollection<PMRUnitTypes> units = new List<PMRUnitTypes>();
List<PMRProjectConfig> UnityTypesObj = new List<PMRProjectConfig>();
//for each config in the project, get the summay
foreach (var c in prj.Configs)
{
//add the buildings
if (c.PB_ID.HasValue && buildings.FirstOrDefault(b => b == c.PB_ID.Value) <= 0)
buildings.Add(c.PB_ID.Value);
//add the complexs
if (c.PC_ID.HasValue && complexes.FirstOrDefault(co => co == c.PC_ID.Value) <= 0)
complexes.Add(c.PC_ID.Value);
//add the wings
if (c.PW_ID.HasValue && wings.FirstOrDefault(w => w == c.PW_ID.Value) <= 0)
wings.Add(c.PW_ID.Value);
//add the floors
if (c.Floor_ID.HasValue)
floors++;
UnityTypesObj.Add(c.UnitTypes);
//add the unit type codes
foreach (var ut in c.UnitTypes)
{
if (unittypes.FirstOrDefault(utc => utc == ut.PUTC_ID) <= 0)
unittypes.Add(ut.PUTC_ID);
}
//get the units
var dscnt = DataServiceLocator.RunStoreProcedureReturnDS("GetPMRUnitsCountFromConfig", 200, new SqlParameter[]{
new SqlParameter{ParameterName = "#PPC_ID", Value= c.PPC_ID}
});
foreach (DataRow r in dscnt.Tables[0].Rows)
{
unitcnt += int.Parse(r["unitCount"].ToString());
}
};
here is my code but on the second foreach loop instead of doing that I was trying to add it to list then loop through it after this initial one is done but I am getting the error above with ICollection. I found out that PMRUnittypes is a ICollection of the config but is there any possible way to do this or write this better which would speed up the code?
the error is on UnityTypesObj.Add(c.UnitTypes); and proj.configs come from the database var cust =DataServiceLocator.GetCustomer_DAO().GetCustomerByID(customerID, Context);
Since c.UnitTypes is a collection, you need to use AddRange instead:
UnityTypesObj.AddRange(c.UnitTypes);

Why I am getting null reference exceptions if the list has a length and no null values in it?

I have this piece of code, nothing fancy:
Modulo1.ForEach(t => fechasMaterias1.Add(t.Fecha.ToString("dddd d", culture)));
Modulo2.ForEach(t => fechasMaterias2.Add(t.Fecha.ToString("dddd d", culture)));
Modulo3.ForEach(t => fechasMaterias3.Add(t.Fecha.ToString("dddd d", culture)));
Modulo1.ForEach(t => horariosMaterias1.Add(t.HorarioInicio.ToString("hh\\:mm") + " a" + t.HorarioFin.ToString("hh\\:mm")));
Modulo2.ForEach(t => horariosMaterias2.Add(t.HorarioInicio.ToString("hh\\:mm") + " a" + t.HorarioFin.ToString("hh\\:mm")));
Modulo3.ForEach(t => horariosMaterias3.Add(t.HorarioInicio.ToString("hh\\:mm") + " a" + t.HorarioFin.ToString("hh\\:mm")));
//Modulo1
if (Modulo1.Count > 0)
{
string dia = String.Empty;
foreach (List<DateTime> item in diasMaterias1)
{
for (int i = 0; i < item.Count; i++)
{
if (i == 0)
dia += "Horario del " + item.ElementAt(i).ToString("d \\de MMMM", culture) + " al ";
else
dia += item.ElementAt(i).ToString("d \\de MMMM", culture);
}
dias1.Add(dia);
}
Modulo1.ForEach(t => view_result1.Add(new HorariosModulosViewModel
{
NombreMateria = t.Nombre,
ModuloNum = "Módulo " + NumerosModulos.Where(x => x.Equals(1)).FirstOrDefault().ToString(),
NombreModulo = ModulosNombre[0],
Grupo = t.Grupo.ToString(),
IdMateriasCursos = t.IdMateriasCursos
}));
for (int i = 0; i < dias1.Count; i++)
{
view_result1.ElementAt(i).dias = dias1.ElementAt(i);
}
for (int i = 0; i < fechasMaterias1.Count; i++)
{
view_result1.ElementAt(i).diasMateria.Add(fechasMaterias1.ElementAt(i));
}
for (int i = 0; i < horariosMaterias1.Count; i++)
{
view_result1.ElementAt(i).horarios.Add(horariosMaterias1.ElementAt(i));
}
And previously I have initialized the lists like so: List<string> fechasMaterias1 = new List<string>(); the same for horariosMaterias1 and 2 and so on, however, I keep getting a null reference exception in the loops on fechasMaterias1 and horariosMaterias1. The strange thing is when I debug they both have a length of 20 (which I expect to, and none of them have null values). I'm completely lost, where may the source of this error come from. view_result1 is a list of a standard POCO. By the way, I make sure Modulo1 has a length and it's only supposed to have that length of 20 elements by now, so basically I'm just building lists from that main list "(Modulo1)" and they hve the same length, so why is the loop crashing?
I just wanted to post the code I made to solve the problem, I got rid of most of the classical foreach or for loops and made use of linq like follows:
//Modulo1
List<string> aux1 = new List<string>();
for (int i = 0; i < fechasMaterias1.Count; i+=4)
{
aux1.Add(fechasMaterias1.ElementAt(i));
}
List<string> aux2 = new List<string>();
for (int i = 0; i < fechasMaterias2.Count; i += 4)
{
aux2.Add(fechasMaterias2.ElementAt(i));
}
List<string> aux3 = new List<string>();
for (int i = 0; i < fechasMaterias3.Count; i += 4)
{
aux3.Add(fechasMaterias3.ElementAt(i));
}
fechasMaterias1 = aux1;
fechasMaterias2 = aux2;
fechasMaterias3 = aux3;
if (Modulo1.Count > 0)
{
string dia = String.Empty;
foreach (List<DateTime> item in diasMaterias1)
{
for (int i = 0; i < item.Count; i++)
{
if (i == 0)
dia += "Horario del " + item.ElementAt(i).ToString("d \\de MMMM", culture) + " al ";
else
dia += item.ElementAt(i).ToString("d \\de MMMM", culture);
}
}
dias1.Add(dia);
Modulo1.ForEach(t => view_result1.Add(new HorariosModulosViewModel
{
NombreMateria = t.Nombre,
ModuloNum = "Módulo " + NumerosModulos.Where(x => x.Equals(1)).FirstOrDefault().ToString(),
NombreModulo = ModulosNombre[0],
Grupo = t.Grupo.ToString(),
IdMateriasCursos = t.IdMateriasCursos
}));
for (int i = 0; i < dias1.Count; i++)
{
view_result1.ElementAt(i).dias = dias1.FirstOrDefault();
}
view_result1.ForEach(t => t.diasMateria = fechasMaterias1);
var materiasListado1 = Modulo1.GroupBy(t=> t.IdMateriasCursos).ToList();
foreach(var item in materiasListado1) {
horariosMaterias1.Add(new Dictionary<int, string>() {{item.Key, (from U in item where U.IdMateriasCursos.Equals(item.Key) select U.HorarioInicio.ToString("hh\\:mm")+" a "+U.HorarioFin.ToString("hh\\:mm")).First()}});
}
view_result1.ForEach(t => t.horarios = horariosMaterias1.Where(p=> p.Keys.Contains(t.IdMateriasCursos)).ToList());
var maestrosListado1 = maestros1.GroupBy(t=> t.IdMateriasCursos).ToList();
foreach(var item in maestrosListado1)
{
losMaestros1.Add(item.Key, (from U in item where U.IdMateriasCursos.Equals(item.Key) select String.Join(" ", U.Titulo, U.Nombres, U.ApellidoPaterno, U.ApellidoMaterno)).ToList());
}
view_result1.ForEach(t => t.Maestros = losMaestros1.Where(x=> x.Key.Equals(t.IdMateriasCursos)).ToDictionary(r=> r.Key, v=> v.Value));
}
that way I iterate faster, I get rid of repeated values and now there are no exceptions in the code. Thank you all!

Trying to update single row in SQL database using LINQ to SQL using a WCF service

What I'm trying to do is create a method using a WCF service to go through One database ( transactions) grab everything from the table which has todays date, then add them to my daily sales table which will have one row per date displaying the profit, the daily takings, the expenses, etc.
I've tried to do it like this
public void CalculateProfit(string Date)
{
decimal takings = 0;// not needed
decimal Expenses = 0;// not needed
using (transactionClassDataContext cont = new transactionClassDataContext())
{
int counter = 0;
DailySale d = new DailySale();
var query = (from q in cont.DailySales where q.Date.Equals(Date) select q);
var query2 = (from r in cont.Transactions where r.Date.Equals(Date) select r);
foreach (var z in query)
{
counter++;
}
if (counter>0)
{
foreach (var y in query2)
{
takings = takings + y.Price;
Expenses = Expenses + 0;
d.Expenses += 0;
d.Takings += y.Price;
d.Profit = d.Takings - d.Expenses;
d.Date = Date;
cont.DailySales.InsertOnSubmit(d);// update the value
cont.SubmitChanges();
}
}
else
{
d.Date = Date;
cont.DailySales.InsertOnSubmit(d);// if there isnt an entry for todays date, add one
cont.SubmitChanges();
}
}
}
}
}
But all it does is throw this error "Cannot add an entity that already exists."
Most similar questions have said I need to create a new instance of d in the foreach, but all that seems to do is add loads of records to m daily sales, when all I want is one row with an updated total.
Any ideas?
You should move the DailySale d = new DailySale(); into the scope(s) where it is used.
You're adding same object for each turn in foreach statement.
1) You can move this lines outside of foreach :
cont.DailySales.InsertOnSubmit(d);// update the value
cont.SubmitChanges();
2) Insert the object in first turn. Update same object in following turns.
cont.UpdateObject(d);
cont.SaveChanges();
You should insert only once
using (transactionClassDataContext cont = new transactionClassDataContext())
{
int counter = 0;
DailySale d = new DailySale();
cont.DailySales.InsertOnSubmit(d);// **INSERT** the value
And update the rest of the times
var query = (from q in cont.DailySales where q.Date.Equals(Date) select q);
var query2 = (from r in cont.Transactions where r.Date.Equals(Date) select r);
foreach (var z in query)
{
counter++;
}
if (counter>0)
{
foreach (var y in query2)
{
takings = takings + y.Price;
Expenses = Expenses + 0;
d.Expenses += 0;
d.Takings += y.Price;
d.Profit = d.Takings - d.Expenses;
d.Date = Date;
cont.SubmitChanges(); // *** left it here but better move it outside the foreach,
}
The `cont.SubmitChanges(); can even be moved completely to the end so you have only one transaction.
it turns out I was changing the d ( the daily sales table) instead of changing the " var r"
DailySale d = new DailySale();
var query = (from q in cont.DailySales where q.Date.Equals(Date) select q);
foreach (var z in query)
{
counter++;
}
if (counter>0)
{
foreach (var r in query)
{
r.Takings = r.Takings + (decimal)price; // here i was using d instead of r
r.Profit = r.Takings - r.Expenses;
}
cont.SubmitChanges();
Thanks for the help .

Static methods getting slower in when accesses by multiple threads

I have a situation where my C# application with .Net 4 is accessing a static method within a static class making the method perform slower than when accessed by a single thread. Say for example, If the method is called by a single thread it takes around 1.5 minutes to complete, whereas when called by 2 threads it takes 4 minutes to complete.
Any ideas/suggestion/best practices to increase the performance is highly appreciated. Thanks in advance for your responses.
Some more info:
This is an application which was using threadpool earlier to perform threading in some parts. I introduced parallel tasks. Hence it's a mix up of TPL and older Thread pool. Say for example one parallel task can have multiple threads. The machine has 24 CPU cores with 64GB RAM. I ran 2 processes which would have split to 5 threads each totalling upto 10 threads. During this the process got slower. I am pasting the code here for those who would like to inspect it and provide suggestions. Sorry for pasting long code. The code may not be having all current latest features as this was coded few years ago. Thanks once again.
public static class Property11
{
/// <summary>
/// Splits agg rows to separate commands where the reference parameters are included for each command.
/// </summary>
/// <param name="worksheetID">The current worksheet ID.</param>
/// <param name="propertyID">The current property ID.</param>
/// <param name="ccrFormObj">The ccr form object.</param>
public static void SplitAggregateIncludeReferenceParameterCCRToDTH(PropertyCall propertyCallObj)
{
string worksheetID = propertyCallObj.WorksheetID;
int propertyID = propertyCallObj.PropertyID;
IDClass nextIDObj = propertyCallObj.NextIDObj;
CCRFormStructure ccrFormObj = propertyCallObj.CCRFormObj;
List<CCRFormStructure> ccrFormObjsToAdd = propertyCallObj.CCRFormObjToAddList;
DateTime dtProp = DateTime.Now;
System.Diagnostics.Debug.Print("Start time property = " + propertyCallObj.PropertyID + ", worksheet = " + propertyCallObj.WorksheetID + ": " + dtProp.ToString());
try
{
// Get all rows for worksheet
List<WorksheetRow> rowListForWorksheet =
(from wr in ccrFormObj.myWorksheetRowList
where wr.WorksheetID == worksheetID
select wr).ToList();
// Get all parameters for worksheet
List<WorksheetRowParameter> rowParameterListForWorksheet =
(from wrp in ccrFormObj.myWorksheetRowParameterList
join wr in rowListForWorksheet
on wrp.WorksheetRowID equals wr.ID
select wrp).ToList();
// Get all agg rows in worksheet
List<AggRow> aggRowsInWorksheet =
(from ar in ccrFormObj.myAggRowList
join wsrp in rowParameterListForWorksheet
on ar.WorksheetRowParameterID equals wsrp.ID
select ar).ToList();
// Get all agg row parameters in worksheet
List<AggRowParameter> aggParametersInWorksheet =
(from arp in ccrFormObj.myAggRowParameterList
join ar in aggRowsInWorksheet
on arp.AggRowID equals ar.ID
select arp).ToList();
// Get all command mappings for worksheet
List<CommandMappingObj> commandMappingListForWorksheet =
(from cm in ccrFormObj.commandMappingList
join wr in rowListForWorksheet
on cm.WorksheetRowID equals wr.ID
select cm).ToList();
// Get all parameter mappings for worksheet
List<ParameterMappingObj> parameterMappingListForWorksheet =
(from pm in ccrFormObj.parameterMappingList
join cm in commandMappingListForWorksheet
on pm.CommandMappingObjID equals cm.ID
select pm).ToList();
// Get all property objects for worksheet
List<ParameterPropertyObj> propertyList =
(from ppo in ccrFormObj.parameterPropertiesList
where ppo.ID == propertyID && ppo.WorksheetID == worksheetID
select ppo).ToList();
//List<WorksheetRow> rowsToRemove = new List<WorksheetRow>();
WorksheetRowParameter currentWorksheetRowParameter;
AggRow currentAggRow;
AggRowParameter currentAggRowParameter;
AggRow currentSteeringAggRow;
AggRowParameter currentSteeringAggRowParameter;
int newIDIndex = 0;
List<string> worksheetRowsWithoutTooLongCommandRows = new List<string>();
WorksheetRow newWSR = new WorksheetRow();
CommandMappingObj newCMO = new CommandMappingObj();
WorksheetRow newWSRForOrigRow = new WorksheetRow();
CommandMappingObj newChangeCMO = new CommandMappingObj();
List<string> steeringParameters;
IEnumerable<WorksheetRowParameter> parameterListForRow;
IEnumerable<WorksheetRowParameter> currentSteeringParameters;
string newCMOID;
ParameterMappingObj newPMO;
WorksheetRowParameter newWSRP;
string newWSRID;
string newID;
IEnumerable<string> commandsWithPropertyParameterForRow;
Hashtable htPropertyParamAndSteeringParameters = new Hashtable();
List<string> steeringParametersForProperty;
WorksheetRowParameter currentWorksheetRowPropertyParameter;
bool removeOrigRow = false;
bool firstRowForAggCreated = false;
List<WorksheetRowParameter> propParamListForFirstCreatedRow = new List<WorksheetRowParameter>();
List<string> propParamUsedAsSteeringList = new List<string>();
foreach (ParameterPropertyObj propertyParameter in propertyList)
{
if (propertyParameter.SecondaryPropertyInfo != null && propertyParameter.SecondaryPropertyInfo != "")
{
steeringParameters = propertyParameter.SecondaryPropertyInfo.Split(",".ToCharArray()).ToList();
}
else
{
steeringParameters = new List<string>();
}
htPropertyParamAndSteeringParameters.Add(propertyParameter.Parameter, steeringParameters);
}
var aggListForRow =
from ar in aggRowsInWorksheet
join arp in aggParametersInWorksheet
on ar.ID equals arp.AggRowID
select new
{
AggRow = ar,
AggRowParameter = arp
};
var worksheetRowsWithRepParam =
from wrp in rowParameterListForWorksheet
where htPropertyParamAndSteeringParameters.Contains(wrp.Parameter)
join al in aggListForRow
on wrp.ID equals al.AggRow.WorksheetRowParameterID
into aggList
where aggList.Count() > 0
select new
{
WorksheetRowParameter = wrp,
AggList = aggList
};
foreach (WorksheetRow worksheetRow in rowListForWorksheet.ToList())
{
var worksheetRowWithRepParam =
worksheetRowsWithRepParam.Where(wrp => wrp.WorksheetRowParameter.WorksheetRowID == worksheetRow.ID);
if (worksheetRowWithRepParam.Count() > 0)
{
firstRowForAggCreated = false;
var currentMappingList =
from cmo in commandMappingListForWorksheet
where cmo.WorksheetRowID == worksheetRow.ID
join pmo in parameterMappingListForWorksheet
on cmo.ID equals pmo.CommandMappingObjID
into parameterMappingList
select new
{
CommandMapping = cmo,
ParameterMappingList = parameterMappingList
};
IEnumerable<ParameterPropertyObj> sortedPropertyList =
from wrwrp in worksheetRowWithRepParam
join ppo in propertyList
on wrwrp.WorksheetRowParameter.Parameter equals ppo.Parameter
orderby wrwrp.AggList.Count() descending
select ppo;
propParamUsedAsSteeringList.Clear();
foreach (ParameterPropertyObj ppo in sortedPropertyList)
{
if (!propParamUsedAsSteeringList.Contains(ppo.Parameter))
{
var currentWorksheetRowsWithRepParam =
worksheetRowWithRepParam.Where(p => p.WorksheetRowParameter.Parameter == ppo.Parameter);
if (currentWorksheetRowsWithRepParam.Count() == 0)
{
continue;
}
var currentWorksheetRowWithRepParam = currentWorksheetRowsWithRepParam.ElementAt(0);
var currentAggList = currentWorksheetRowWithRepParam.AggList;
if (!firstRowForAggCreated)
{
currentWorksheetRowPropertyParameter = currentWorksheetRowWithRepParam.WorksheetRowParameter;
}
else
{
currentWorksheetRowPropertyParameter = propParamListForFirstCreatedRow.Where(p => p.Parameter == ppo.Parameter).ElementAt(0);
}
if (currentAggList.Count() > 1)
{
removeOrigRow = true;
steeringParametersForProperty = (List<string>)htPropertyParamAndSteeringParameters[ppo.Parameter];
currentSteeringParameters =
from wrp in rowParameterListForWorksheet
where wrp.WorksheetRowID == worksheetRow.ID
&& steeringParametersForProperty.Contains(wrp.Parameter)
select wrp;
commandsWithPropertyParameterForRow =
from cml in currentMappingList
where cml.ParameterMappingList.Count(pmo => pmo.Name == ppo.Parameter) > 0
select cml.CommandMapping.Name;
propParamUsedAsSteeringList.AddRange(
from sp in sortedPropertyList
where sp.Parameter != ppo.Parameter
join csp in currentSteeringParameters
on sp.Parameter equals csp.Parameter
select csp.Parameter);
// CREATE NEW WORKSHEET ROWS FOR EACH BUT THE FIRST AGG ROW PARAMETER
for (int i = 0; i < currentAggList.Count(); i++)
{
currentAggRow = currentAggList.ElementAt(i).AggRow;
currentAggRowParameter = currentAggList.ElementAt(i).AggRowParameter;
if (i == 0)
{
currentWorksheetRowPropertyParameter.Value = currentAggRowParameter.Value;
if (!firstRowForAggCreated)
{
propParamListForFirstCreatedRow.Clear();
newWSRID = newIDIndex.ToString().PadLeft(3, '0');
newID = newWSRID;
if (!worksheetRow.ID.Contains(','))
{
newID = "," + newWSRID;
}
newWSRForOrigRow = new WorksheetRow
{
ID = worksheetRow.ID + newID,
OriginalWorksheetRowID = worksheetRow.OriginalWorksheetRowID,
WorksheetID = worksheetRow.WorksheetID
};
ccrFormObj.myWorksheetRowList.Add(newWSRForOrigRow);
parameterListForRow =
from wrp in rowParameterListForWorksheet
where wrp.WorksheetRowID == worksheetRow.ID
select wrp;
foreach (WorksheetRowParameter currentParameter in parameterListForRow)
{
newID = "";
if ((currentParameter.ID != null) && (!currentParameter.ID.Contains(',')))
{
newID = ",";
}
newID += newIDIndex.ToString().PadLeft(3, '0');
newWSRP = new WorksheetRowParameter
{
ID = currentParameter.ID + newID,
OriginalParameterID = currentParameter.OriginalParameterID,
WorksheetRowID = newWSRForOrigRow.ID,
Parameter = currentParameter.Parameter,
Value = currentParameter.Value,
Disabled = currentParameter.Disabled
};
if (htPropertyParamAndSteeringParameters.Contains(newWSRP.Parameter)
&& newWSRP.Parameter != ppo.Parameter)
{
// TODO: IF AGG, TAKE AGG POS VALUE
var steeringParamAggList =
from wrwrp in worksheetRowWithRepParam
where wrwrp.WorksheetRowParameter.Parameter == newWSRP.Parameter
select wrwrp.AggList;
if (steeringParamAggList.Count() > 0)
{
if (steeringParamAggList.ElementAt(0).Count() > i)
{
currentSteeringAggRow = steeringParamAggList.ElementAt(0).ElementAt(i).AggRow;
currentSteeringAggRowParameter = steeringParamAggList.ElementAt(0).ElementAt(i).AggRowParameter;
newWSRP.Value = currentSteeringAggRowParameter.Value;
ccrFormObj.myAggRowParameterList.Remove(currentSteeringAggRowParameter);
ccrFormObj.myAggRowList.Remove(currentSteeringAggRow);
ccrFormObj.myWorksheetRowParameterList.Add(newWSRP);
}
}
else
{
ccrFormObj.myWorksheetRowParameterList.Add(newWSRP);
}
propParamListForFirstCreatedRow.Add(newWSRP);
}
else
{
ccrFormObj.myWorksheetRowParameterList.Add(newWSRP);
}
}
foreach (var currentMapping in currentMappingList)
{
// Re-point original command mapping to new row
newCMOID = newIDIndex.ToString().PadLeft(3, '0');
if (!currentMapping.CommandMapping.ID.Contains(','))
{
newID = "," + newCMOID;
}
// Create new command mapping object
newCMO = new CommandMappingObj
{
ID = currentMapping.CommandMapping.ID + newID,
Name = currentMapping.CommandMapping.Name,
WorksheetRowID = newWSRForOrigRow.ID
};
ccrFormObj.commandMappingList.Add(newCMO);
foreach (ParameterMappingObj pmo in currentMapping.ParameterMappingList)
{
newPMO = new ParameterMappingObj
{
Name = pmo.Name,
CommandMappingObjID = newCMO.ID
};
ccrFormObj.parameterMappingList.Add(newPMO);
}
}
firstRowForAggCreated = true;
}
}
else
{
newWSRID = newIDIndex.ToString().PadLeft(3, '0');
newID = newWSRID;
if (!worksheetRow.ID.Contains(','))
{
newID = "," + newWSRID;
}
newWSR = new WorksheetRow
{
ID = worksheetRow.ID + newID,
OriginalWorksheetRowID = worksheetRow.OriginalWorksheetRowID,
WorksheetID = worksheetRow.WorksheetID
};
ccrFormObj.myWorksheetRowList.Add(newWSR);
foreach (WorksheetRowParameter currentSteeringParameter in currentSteeringParameters)
{
newID = "";
if ((currentSteeringParameter.ID != null) && (!currentSteeringParameter.ID.Contains(',')))
{
newID = ",";
}
newID += newIDIndex.ToString().PadLeft(3, '0');
newWSRP = new WorksheetRowParameter
{
ID = currentSteeringParameter.ID + newID,
OriginalParameterID = currentSteeringParameter.OriginalParameterID,
WorksheetRowID = newWSR.ID,
Parameter = currentSteeringParameter.Parameter,
Value = currentSteeringParameter.Value,
Disabled = currentSteeringParameter.Disabled
};
var steeringParamAggList =
from wrwrp in worksheetRowWithRepParam
where wrwrp.WorksheetRowParameter.Parameter == newWSRP.Parameter
select wrwrp.AggList;
if (steeringParamAggList.Count() > 0)
{
if (steeringParamAggList.ElementAt(0).Count() > i)
{
currentSteeringAggRow = steeringParamAggList.ElementAt(0).ElementAt(i).AggRow;
currentSteeringAggRowParameter = steeringParamAggList.ElementAt(0).ElementAt(i).AggRowParameter;
newWSRP.Value = currentSteeringAggRowParameter.Value;
ccrFormObj.myAggRowParameterList.Remove(currentSteeringAggRowParameter);
ccrFormObj.myAggRowList.Remove(currentSteeringAggRow);
ccrFormObj.myWorksheetRowParameterList.Add(newWSRP);
}
}
else
{
ccrFormObj.myWorksheetRowParameterList.Add(newWSRP);
}
}
// Add rep param
newID = "";
if ((currentWorksheetRowPropertyParameter.ID != null) && (!currentWorksheetRowPropertyParameter.ID.Contains(',')))
{
newID = ",";
}
newID += newIDIndex.ToString().PadLeft(3, '0');
newWSRP = new WorksheetRowParameter
{
ID = currentWorksheetRowPropertyParameter.ID + newID,
OriginalParameterID = currentWorksheetRowPropertyParameter.OriginalParameterID,
WorksheetRowID = newWSR.ID,
Parameter = currentWorksheetRowPropertyParameter.Parameter,
Value = currentAggRowParameter.Value,
Disabled = currentWorksheetRowPropertyParameter.Disabled
};
ccrFormObj.myWorksheetRowParameterList.Add(newWSRP);
foreach (var currentMapping in currentMappingList)
{
if (commandsWithPropertyParameterForRow.Contains(currentMapping.CommandMapping.Name))
{
newCMOID = newIDIndex.ToString().PadLeft(3, '0');
if (!currentMapping.CommandMapping.ID.Contains(','))
{
newID = "," + newCMOID;
}
// Create new command mapping object
newCMO = new CommandMappingObj
{
ID = currentMapping.CommandMapping.ID + newID,
Name = currentMapping.CommandMapping.Name,
WorksheetRowID = newWSR.ID
};
ccrFormObj.commandMappingList.Add(newCMO);
foreach (ParameterMappingObj pmo in currentMapping.ParameterMappingList)
{
if ((pmo.Name == ppo.Parameter) || (currentSteeringParameters.Count(p => p.Parameter == pmo.Name) > 0))
{
newPMO = new ParameterMappingObj
{
Name = pmo.Name,
CommandMappingObjID = newCMO.ID
};
ccrFormObj.parameterMappingList.Add(newPMO);
}
}
}
}
}
newIDIndex++;
ccrFormObj.myAggRowParameterList.Remove(currentAggRowParameter);
ccrFormObj.myAggRowList.Remove(currentAggRow);
}
}
else
{
currentAggRow = currentAggList.ElementAt(0).AggRow;
currentAggRowParameter = currentAggList.ElementAt(0).AggRowParameter;
currentWorks
There is nothing intrinsic about a static method that would make it slower when accessed by multiple threads, unless for example:
you have some shared resource that is being a throttle, such as a shared lock, or going to a single UI thread
you have more threads than available CPU cores, and it is simply having to do lots of switching
you are maxing out some other resource, such as disk IO, network IO, etc
Since you haven't posted any code, we can only guess.

how to assign linq result to multidimensional array

i want to assign the linq result to a multidimensional array and the below is my code, can any one tell me what i am doing wrong.
var query = (from b in db.FourBodyImages
where b.Status == true
orderby b.CreaedDate descending
select new { b.BodyImage, b.Description, b.HeaderName }
).Take(4).ToArray();
if(query.Count()>0)
{
string[,,] x = new string[4, 4,4];
x[,,] = query;
for (int i = 0; i < query.Length; i++)
{
if (i == 0)
{
imgBody1.ImageUrl = "FourBodyImages/" + x[0,0,0].ToString();
}
if (i == 1)
{
imgBody2.ImageUrl = "FourBodyImages/" + x[1,1,1].ToString();
}
if (i == 2)
{
imgBody3.ImageUrl = "FourBodyImages/" + x[2,2,2].ToString();
}
if (i == 3)
{
imgBody4.ImageUrl = "FourBodyImages/" + x[3,3,3].ToString();
}
}
}
If you just need to get 4 objects from the database, and then use them to fill 4 images, all you need to do is:
//this generates an array of (up to 4) objects of an anonymous type
var query = (from b in db.FourBodyImages
where b.Status == true
orderby b.CreaedDate descending
select new { b.BodyImage, b.Description, b.HeaderName }
).Take(4).ToArray();
//no need for count, we can use the array's length
if (query.Length < 4)
{
//i have no idea about your requirements,
//but if we have less than 4 images - panic
throw new InvalidOperationException()
}
//no need for the "for-if", that's an anti-patern
imgBody1.ImageUrl = "FourBodyImages/" + query[0].BodyImage;
imgBody2.ImageUrl = "FourBodyImages/" + query[1].BodyImage;
imgBody3.ImageUrl = "FourBodyImages/" + query[2].BodyImage;
imgBody4.ImageUrl = "FourBodyImages/" + query[3].BodyImage;
It's not clear why you want a three-dimensional array to start with. You're only taking 4 values... why is that not just a one-dimensional array?
var query = (from b in db.FourBodyImages
where b.Status == true
orderby b.CreaedDate descending
select new { b.BodyImage, b.Description, b.HeaderName }
).Take(4).ToArray();
var bodies = new[] { imgBody1, imgBody2, imgBody3, imgBody4 };
for (int i = 0; i < query.Length; i++)
{
// Or whichever property you're interested in...
bodies[i].ImageUrl = "FourBodyImages/" + query[i].BodyImage;
}
If this doesn't help, please give us more idea of what you're actually trying to achieve. Why does your query return three properties, for example, and how do you want to use them?

Categories