How to use linq to "flatten" an hierachy? - c#

Given the following code example, how do I:
Get the commented out lines in the unfiltered list to work (without changing the definition of Result)?
Get the commented out lines in the filtered list to work (without changing the definition of Result)? From my maths it should give 32 records. Hopefully my output intent is clear enough for others to understand
Any questions feel free to ask
Regards
Kyle
//Populate data
var alphas = new List<Alpha>();
for (int a = 1; a <= 10; a++)
{
var alpha = new Alpha() { Id = a, Name = "A" + a };
for (int b = 1; b <= 10; b++)
{
var beta = new Beta() { Id = b, Name = "B" + b };
for (int c = 1; c <= 10; c++)
{
var charlie = new Charlie() { Id = c, Name = "C" + c };
for (int d = 1; d <= 10; d++)
{
var delta = new Delta() { Id = d, Name = "D" + d };
charlie.Deltas.Add(delta);
}
beta.Charlies.Add(charlie);
}
alpha.Betas.Add(beta);
}
alphas.Add(alpha);
}
//Get results into required format without filtering
var unfilteredResults = alphas.Select(a => new Result
{
AId = a.Id,
AName = a.Name,
//BId = a.Betas.Select(b => b.Id),
//BName = a.Betas.Select(b => b.Name),
//CId = a.Betas.Select(b => b.Charlies.Select(c => c.Id)),
//CName = a.Betas.Select(b => b.Charlies.Select(c => c.Name)),
//DId = a.Betas.Select(b => b.Charlies.Select(c => c.Deltas.Select(d => d.Id))),
//DName = a.Betas.Select(b => b.Charlies.Select(c => c.Deltas.Select(d => d.Name)))
});
var whiteListAIds = new List<int>() { 1, 2 };
var whiteListBIds = new List<int>() { 3, 4 };
var whiteListCIds = new List<int>() { 5, 6 };
var whiteListDIds = new List<int>() { 7, 8 };
//Get results into required format with filtering
var filteredResults = alphas.Where(a => whiteListAIds.Contains(a.Id)).Select(a => new Result
{
AId = a.Id,
AName = a.Name,
//BId = a.Betas.Where(b => whiteListBIds.Contains(b.Id)).Select(b => b.Id),
//BName = a.Betas.Where(b => whiteListBIds.Contains(b.Id)).Select(b => b.Name),
//CId = a.Betas.Where(b => whiteListBIds.Contains(b.Id)).Select(b => b.Charlies.Where(c => whiteListCIds.Contains(c.Id)).Select(c => c.Id)),
//CName = a.Betas.Where(b => whiteListBIds.Contains(b.Id)).Select(b => b.Charlies.Where(c => whiteListCIds.Contains(c.Id)).Select(c => c.Name)),
//DId = a.Betas.Where(b => whiteListBIds.Contains(b.Id)).Select(b => b.Charlies.Where(c => whiteListCIds.Contains(c.Id)).Select(c => c.Deltas.Where(d => whiteListDIds.Contains(d.Id)).Select(d => d.Id))),
//DName = a.Betas.Where(b => whiteListBIds.Contains(b.Id)).Select(b => b.Charlies.Where(c => whiteListCIds.Contains(c.Id)).Select(c => c.Deltas.Where(d => whiteListDIds.Contains(d.Id)).Select(d => d.Name)))
});
class Alpha
{
public int Id { get; set; }
public string Name { get; set; }
public List<Beta> Betas { get; set; } = new List<Beta>();
}
class Beta
{
public int Id { get; set; }
public string Name { get; set; }
public List<Charlie> Charlies { get; set; } = new List<Charlie>();
}
class Charlie
{
public int Id { get; set; }
public string Name { get; set; }
public List<Delta> Deltas { get; set; } = new List<Delta>();
}
class Delta
{
public int Id { get; set; }
public string Name { get; set; }
}
class Result
{
public int AId { get; set; }
public string AName { get; set; }
public int BId { get; set; }
public string BName { get; set; }
public int CId { get; set; }
public string CName { get; set; }
public int DId { get; set; }
public string DName { get; set; }
}

Got it working as below thanks to the first answer linq selectmany flatten multiple levels
Basically had to combine .SelectMany() on the "outer" parents and .Select() on the last/inner child.
//Populate data
var alphas = new List<Alpha>();
for (int a = 1; a <= 10; a++)
{
var alpha = new Alpha() { Id = a, Name = "A" + a };
for (int b = 1; b <= 10; b++)
{
var beta = new Beta() { Id = b, Name = "B" + b };
for (int c = 1; c <= 10; c++)
{
var charlie = new Charlie() { Id = c, Name = "C" + c };
for (int d = 1; d <= 10; d++)
{
var delta = new Delta() { Id = d, Name = "D" + d };
charlie.Deltas.Add(delta);
}
beta.Charlies.Add(charlie);
}
alpha.Betas.Add(beta);
}
alphas.Add(alpha);
}
var unfilteredResults = alphas.SelectMany(a => a.Betas.SelectMany(b=> b.Charlies.SelectMany(c=> c.Deltas.Select(d => new Result
{
AId = a.Id,
AName = a.Name,
BId = b.Id,
BName = b.Name,
CId = c.Id,
CName = c.Name,
DId = d.Id,
DName = d.Name
}))));
var whiteListAIds = new List<int>() { 1, 2 };
var whiteListBIds = new List<int>() { 3, 4 };
var whiteListCIds = new List<int>() { 5, 6 };
var whiteListDIds = new List<int>() { 7, 8 };
//Get results into required format with filtering
var filteredResults = unfilteredResults.Where(r => whiteListAIds.Contains(r.AId) && whiteListBIds.Contains(r.BId) && whiteListCIds.Contains(r.CId) && whiteListDIds.Contains(r.DId));
Console.WriteLine("Finished");
class Alpha
{
public int Id { get; set; }
public string Name { get; set; }
public List<Beta> Betas { get; set; } = new List<Beta>();
}
class Beta
{
public int Id { get; set; }
public string Name { get; set; }
public List<Charlie> Charlies { get; set; } = new List<Charlie>();
}
class Charlie
{
public int Id { get; set; }
public string Name { get; set; }
public List<Delta> Deltas { get; set; } = new List<Delta>();
}
class Delta
{
public int Id { get; set; }
public string Name { get; set; }
}
class Result
{
public int AId { get; set; }
public string AName { get; set; }
public int BId { get; set; }
public string BName { get; set; }
public int CId { get; set; }
public string CName { get; set; }
public int DId { get; set; }
public string DName { get; set; }
}

Related

How to prevent items in a list returning "0" when not filled in and they supposed to be "null"?

This was kind of a hard question to ask but this is my problem:
I'm populating a grid with data I obtain from a different class, this class uses a (generic) Model that can represent multiple models:
Model(can represent Vessel or Container):
public class DataGridInstallationRow
{
[Key]
public string Name { get; set; }
//Vessel
public int IMO { get; set; }
public int MMSI { get; set; }
public int EEOI { get; set; }
public int FOC { get; set; }
[Display(Name = "Total Fuel Mass")]
public int TotalFuelMass { get; set; }
[Display(Name = "Average Speed")]
public int AverageSpeed { get; set; }
[Display(Name = "Total Distance Sailed")]
public int TotalDistanceSailed { get; set; }
//Container
[Display(Name = "Generated by Sun")]
public int EnergyGeneratedBySun { get; set; }
[Display(Name = "Generated by Wind")]
public int EnergyGeneratedByWind { get; set; }
[Display(Name = "Generated by Generator")]
public int EnergyGeneratedByGenerator { get; set; }
[Display(Name = "Consumed by EV's")]
public int EnergyConsumedByEV { get; set; }
[Display(Name = "Consumed by Construction Site")]
public int EnergyConsumedByConstructionSite { get; set; }
}
This model is used in my provider:
if (fleet.Type.Equals("Container"))
{
return Enumerable.Range(0, 10).Select(i => new DataGridInstallationRow()
{
Name = $"Container {i}",
EnergyGeneratedBySun = 13,
EnergyGeneratedByWind = 19,
EnergyGeneratedByGenerator = 3,
EnergyConsumedByEV = 15,
EnergyConsumedByConstructionSite = 24
}).ToList();
}
else
{
return Enumerable.Range(0, 10).Select(i => new DataGridInstallationRow()
{
Name = $"Vessel {i}",
IMO = 231,
MMSI = 1344,
EEOI = 8121,
FOC = 123,
TotalFuelMass = 6817,
AverageSpeed = 14,
TotalDistanceSailed = 1560
}).ToList();
}
As u can see, depending on the Fleet.Type, one of the other is filled in. If Fleet.Type is container the object will look like this:
As u can see the properties of "Vessel" is filled in aswell with all "0", I want these to be null instead of "0" because my datagrid is filled with both models now:
Whats best practice to avoid and fix this?
UPDATE
Applied solution of Dogac:
if (fleet.Type.Equals("Container"))
{
return Enumerable.Range(0, 10).Select(i => new DataGridInstallationRow()
{
Name = $"Container {i}",
EnergyGeneratedBySun = 13,
EnergyGeneratedByWind = 19,
EnergyGeneratedByGenerator = 3,
EnergyConsumedByEV = 15,
EnergyConsumedByConstructionSite = 24
}).Where(row =>
{
return row.EnergyGeneratedBySun.HasValue &&
row.EnergyGeneratedByWind.HasValue &&
row.EnergyGeneratedByGenerator.HasValue &&
row.EnergyConsumedByEV.HasValue &&
row.EnergyConsumedByConstructionSite.HasValue;
}).ToList();
}
else
{
return Enumerable.Range(0, 10).Select(i => new DataGridInstallationRow()
{
Name = $"Vessel {i}",
IMO = 231,
MMSI = 1344,
EEOI = 8121,
FOC = 123,
TotalFuelMass = 6817,
AverageSpeed = 14,
TotalDistanceSailed = 1560
}).Where(row =>
{
return row.IMO.HasValue &&
row.MMSI.HasValue &&
row.EEOI.HasValue &&
row.FOC.HasValue &&
row.TotalFuelMass.HasValue &&
row.AverageSpeed.HasValue &&
row.TotalDistanceSailed.HasValue;
}).ToList();
}
Is still not working, im again receiving a list with nullable items.
Thanks in advance
Try making all properties nullable.
Like this:
// Vessel
public int? IMO { get; set; }
public int? MMSI { get; set; }
public int? EEOI { get; set; }
public int? FOC { get; set; }
Edit regarding comment:
Enumerable.Range(0, 10).Select(i => new DataGridInstallationRow()
{
Name = $"Vessel {i}",
IMO = 231,
MMSI = 1344,
EEOI = 8121,
FOC = 123,
TotalFuelMass = 6817,
AverageSpeed = 14,
TotalDistanceSailed = 1560
}).Where(row =>
{
return row.IMO.HasValue &&
row.MMSI.HasValue &&
row.EEOI.HasValue &&
row.FOC.HasValue &&
row.TotalFuelMass.HasValue &&
row.AverageSpeed.HasValue &&
row.TotalDistanceSailed.HasValue;
}).ToList();

What is the alternate way of using LINQ ForEach loop?

medicineList.ForEach(x =>
{
DoctorsOrderViewModel vm = new DoctorsOrderViewModel()
{
DrugID = x.PKID,
Name = x.Name,
DrugName = x.Name,
UnitName = x.UnitName,
CategoryID = x.CategoryID,
CategoryName = x.CategoryName,
DosageFormID = x.DosageFormID,
InventoryTypeID = x.InventoryTypeID,
};
temp.Add(vm);
this.DrugItemsComboForSearch.Add(vm);
DoctorsOrderViewModel vm2 = new DoctorsOrderViewModel() { CategoryID = x.CategoryID, CategoryName = x.CategoryName, };
if (!this.MedicineCategoryItemsCombo.Select(y => y.CategoryID).Contains(x.CategoryID))
{
this.MedicineCategoryItemsCombo.Add(vm2);
}
});
In my Case for 13000 Medicine this code took 8-10 sec to complete but its too lengthy considering performance issue. How can i optimized this?
What is the alternate way of using LINQ ForEach loop?
A standard foreach.
How can i optimized this
As to performance, its not yourForEach that's the problem, its probably the select and contains ,consider using a ToHashSet once
var set = this.MedicineCategoryItemsCombo.Select(y => y.CategoryID).ToHashSet();
Then you can use in your loop
if (set.Add(x.CategoryID))
{
this.MedicineCategoryItemsCombo.Add(vm2);
}
However on reading your code, this can probably be optimised with a better query and Where, then do a Select
Update: I got some time so I was able to write a complete example:
The results:
10x OPWay for 13000 medicines and 1000 categories: 00:00:03.8986663
10x MyWay for 13000 medicines and 1000 categories: 00:00:00.0879221
Summary
Use AddRange after a transformation with .Select
Use Distinct at the end of the process rather than scanning and adding one by one in each loop.
Solution
public static List<(string catId, string catName)> MyWay(List<Medicine> medicineList)
{
var temp = new List<DoctorsOrderViewModel>();
var DrugItemsComboForSearch = new List<DoctorsOrderViewModel>();
var transformed = medicineList.Select(x =>
{
return new DoctorsOrderViewModel()
{
DrugID = x.PKID,
Name = x.Name,
DrugName = x.Name,
UnitName = x.UnitName,
CategoryID = x.CategoryID,
CategoryName = x.CategoryName,
DosageFormID = x.DosageFormID,
InventoryTypeID = x.InventoryTypeID,
};
}).ToList(); ;
temp.AddRange(transformed);
DrugItemsComboForSearch.AddRange(transformed);
var MedicineCategoryItemsCombo = transformed.Select(m => (catId: m.CategoryID, catName: m.CategoryName)).Distinct().ToList();
return MedicineCategoryItemsCombo;
}
Full example:
public static class MainClass
{
public class Medicine
{
public string PKID { get; set; }
public string Name { get; set; }
public string UnitName { get; set; }
public string CategoryID { get; set; }
public string CategoryName { get; set; }
public string DosageFormID { get; set; }
public string InventoryTypeID { get; set; }
}
public class DoctorsOrderViewModel
{
public string DrugID { get; set; }
public string Name { get; set; }
public string DrugName { get; set; }
public string UnitName { get; set; }
public string CategoryID { get; set; }
public string CategoryName { get; set; }
public string DosageFormID { get; set; }
public string InventoryTypeID { get; set; }
}
class Category
{
public string CategoryID { get; set; }
}
public static void Main()
{
var medicines = new List<Medicine>();
medicines.AddRange(Enumerable.Range(0, 13000).Select(i => new Medicine()
{
PKID = "PKID" + i,
Name = "Name" + i,
UnitName = "UnitName" + i,
CategoryID = "CategoryID" + i%1000,
CategoryName = "CategoryName for CategoryID" + i%1000,
DosageFormID = "DosageFormID" + i,
InventoryTypeID = "InventoryTypeID" + i,
}));
Stopwatch sw = new Stopwatch();
sw.Start();
List<DoctorsOrderViewModel> comboData = null;
for (int i = 0; i < 10; i++)
{
comboData = OpWay(medicines);
}
var elapsed = sw.Elapsed;
Console.WriteLine($"10x OPWay for {medicines.Count} medicines and {comboData.Count} categories: {elapsed}");
sw.Restart();
List<(string catId, string catName)> comboData2 = null;
for (int i = 0; i < 10; i++)
{
comboData2 = MyWay(medicines);
}
elapsed = sw.Elapsed;
Console.WriteLine($"10x MyWay for {medicines.Count} medicines and {comboData2.Count} categories: {elapsed}");
}
public static List<DoctorsOrderViewModel> OpWay(List<Medicine> medicineList)
{
List<DoctorsOrderViewModel> MedicineCategoryItemsCombo = new List<DoctorsOrderViewModel>();
var temp = new List<DoctorsOrderViewModel>();
var DrugItemsComboForSearch = new List<DoctorsOrderViewModel>();
medicineList.ForEach(x =>
{
DoctorsOrderViewModel vm = new DoctorsOrderViewModel()
{
DrugID = x.PKID,
Name = x.Name,
DrugName = x.Name,
UnitName = x.UnitName,
CategoryID = x.CategoryID,
CategoryName = x.CategoryName,
DosageFormID = x.DosageFormID,
InventoryTypeID = x.InventoryTypeID,
};
temp.Add(vm);
DrugItemsComboForSearch.Add(vm);
DoctorsOrderViewModel vm2 = new DoctorsOrderViewModel() { CategoryID = x.CategoryID, CategoryName = x.CategoryName, };
if (!MedicineCategoryItemsCombo.Select(y => y.CategoryID).Contains(x.CategoryID))
{
MedicineCategoryItemsCombo.Add(vm2);
}
});
return MedicineCategoryItemsCombo;
}
public static List<(string catId, string catName)> MyWay(List<Medicine> medicineList)
{
var temp = new List<DoctorsOrderViewModel>();
var DrugItemsComboForSearch = new List<DoctorsOrderViewModel>();
var transformed = medicineList.Select(x =>
{
return new DoctorsOrderViewModel()
{
DrugID = x.PKID,
Name = x.Name,
DrugName = x.Name,
UnitName = x.UnitName,
CategoryID = x.CategoryID,
CategoryName = x.CategoryName,
DosageFormID = x.DosageFormID,
InventoryTypeID = x.InventoryTypeID,
};
}).ToList(); ;
temp.AddRange(transformed);
DrugItemsComboForSearch.AddRange(transformed);
var MedicineCategoryItemsCombo = transformed.Select(m => (catId: m.CategoryID, catName: m.CategoryName)).Distinct().ToList();
return MedicineCategoryItemsCombo;
}
}
You can use different approach for foreach, which is better than above, also code could be minimised a bit:
foreach (Medicine medicine in medicineList)
{
DoctorsOrderViewModel vm = new DoctorsOrderViewModel()
{
DrugID = x.PKID,
Name = x.Name,
DrugName = x.Name,
UnitName = x.UnitName,
CategoryID = x.CategoryID,
CategoryName = x.CategoryName,
DosageFormID = x.DosageFormID,
InventoryTypeID = x.InventoryTypeID,
};
temp.Add(vm);
this.DrugItemsComboForSearch.Add(vm);
if (!this.MedicineCategoryItemsCombo.Select(y => y.CategoryID ==
x.CategoryID).Any())
{
this.MedicineCategoryItemsCombo.Add(new DoctorsOrderViewModel()
{
CategoryID = x.CategoryID,
CategoryName = x.CategoryName,
};);
}
}

Get 1 record from 2 tables ASP.NET

I am still an ASP.NET amateur and I've been working on an application that needs to calculate the hours an employee has worked if no special events have come up e.g the employee has been sick, I have 2 tables in my database, 1 with the employees. and a second table which holds the events. the events table is filled through a calendar and holds info like dates and who made the event.
My situation:
When the user clicks on an employee's detail page. I want the corresponding record of the employee, and the events he made. So I am assuming that I am looking for a join with linq.
An employee can make more than 1 event, let's say an employee needs to work overtime 3 days this month. then on the detail page, it should select the employee from the employee table and the 3 events from the events table.
Update
Thanks to Vladimir's help, a whole lot of errors are gone and the query works. Though it does not completely work as expected yet. it currently returns 1 employee and 1 event. While the employee that I am testing with, should have 4 events returned.
This is my Context
namespace hrmTool.Models
{
public class MedewerkerMeldingContext : DbContext
{
public MedewerkerMeldingContext() : base("name=temphrmEntities") { }
public DbSet<medewerker> medewerker { get; set; }
public DbSet<medewerker_melding> medewerker_melding { get; set; }
}
}
My current viewModel
namespace hrmTool.Models
{
public class MedewerkerMeldingViewModel
{
//Medewerker tabel
public int ID { get; set; }
public string roepnaam { get; set; }
public string voorvoegsel { get; set; }
public string achternaam { get; set; }
public string tussenvoegsel { get; set; }
public string meisjesnaam { get; set; }
public Nullable<System.DateTime> datum_in_dienst { get; set; }
public Nullable<System.DateTime> datum_uit_dienst { get; set; }
public int aantal_km_woon_werk { get; set; }
public bool maandag { get; set; }
public Nullable<System.TimeSpan> ma_van { get; set; }
public Nullable<System.TimeSpan> ma_tot { get; set; }
public bool dinsdag { get; set; }
public Nullable<System.TimeSpan> di_van { get; set; }
public Nullable<System.TimeSpan> di_tot { get; set; }
public bool woensdag { get; set; }
public Nullable<System.TimeSpan> wo_van { get; set; }
public Nullable<System.TimeSpan> wo_tot { get; set; }
public bool donderdag { get; set; }
public Nullable<System.TimeSpan> do_van { get; set; }
public Nullable<System.TimeSpan> do_tot { get; set; }
public bool vrijdag { get; set; }
public Nullable<System.TimeSpan> vr_van { get; set; }
public Nullable<System.TimeSpan> vr_tot { get; set; }
public bool zaterdag { get; set; }
public Nullable<System.TimeSpan> za_van { get; set; }
public Nullable<System.TimeSpan> za_tot { get; set; }
public bool zondag { get; set; }
public Nullable<System.TimeSpan> zo_van { get; set; }
public Nullable<System.TimeSpan> zo_tot { get; set; }
//Medewerker_Melding combi tabel
public int medewerkerID { get; set; }
public int meldingID { get; set; }
public System.DateTime datum_van { get; set; }
public Nullable<System.DateTime> datum_tot { get; set; }
public int MM_ID { get; set; }
public virtual ICollection<medewerker_melding> medewerker_melding { get; set; }
public virtual medewerker medewerker { get; set; }
}
}
My current query
using (var context = new MedewerkerMeldingContext())
{
var medewerkers = context.medewerker;
var medewerker_meldings = context.medewerker_melding;
var testQuery = from m in medewerkers
join mm in medewerker_meldings on m.ID equals mm.medewerkerID
where m.ID == id
select new MedewerkerMeldingViewModel
{
ID = m.ID,
roepnaam = m.roepnaam,
voorvoegsel = m.voorvoegsel,
achternaam = m.achternaam,
tussenvoegsel = m.tussenvoegsel,
meisjesnaam = m.meisjesnaam,
datum_in_dienst = m.datum_in_dienst,
datum_uit_dienst = m.datum_uit_dienst,
aantal_km_woon_werk = m.aantal_km_woon_werk,
maandag = m.maandag,
ma_van = m.ma_van,
ma_tot = m.ma_tot,
dinsdag = m.dinsdag,
di_van = m.di_van,
di_tot = m.di_tot,
woensdag = m.woensdag,
wo_van = m.wo_van,
wo_tot = m.wo_tot,
donderdag = m.donderdag,
do_van = m.do_van,
do_tot = m.do_tot,
vrijdag = m.vrijdag,
vr_van = m.vr_van,
vr_tot = m.vr_tot,
zaterdag = m.zaterdag,
za_van = m.za_van,
za_tot = m.za_tot,
zondag = m.zondag,
zo_van = m.zo_van,
zo_tot = m.zo_tot,
medewerkerID = mm.medewerkerID,
meldingID = mm.meldingID,
datum_van = mm.datum_van,
datum_tot = mm.datum_tot,
MM_ID = mm.ID
};
var getQueryResult = testQuery.FirstOrDefault();
Debug.WriteLine("Debug testQuery" + testQuery);
Debug.WriteLine("Debug getQueryResult: "+ getQueryResult);
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
if (testQuery == null)
{
return HttpNotFound();
}
return View(getQueryResult);
}
Returns: 1 instance of employee and only 1 event
Expected return: 1 instance of employee, 4 events
In your context DbContext is missing - so Linq to Entity can not find corresponding implementation of the query. And also DbContext operates with the
DbSets - so try:
public class MedewerkerMeldingContext : DbContext
{
public MedewerkerMeldingContext () : base(ConnectionStringKey)
{
};
public DbSet<medewerker> medewerker { get; set; }
public DbSet<medewerker_melding> medewerker_melding { get; set; }
}
then
using (var context = new MedewerkerMeldingContext())
{
var medewerkers = context.medewerker;
var medewerker_meldings = context.medewerker_melding;
var testQuery = from m in medewerkers
join mm in medewerker_meldings on m.ID equals mm.medewerkerID
where m.ID == id
select new MedewerkerMeldingViewModel
{
ID = m.ID,
roepnaam = m.roepnaam,
voorvoegsel = m.voorvoegsel,
achternaam = m.achternaam,
tussenvoegsel = m.tussenvoegsel,
meisjesnaam = m.meisjesnaam,
datum_in_dienst = m.datum_in_dienst,
datum_uit_dienst = m.datum_uit_dienst,
aantal_km_woon_werk = m.aantal_km_woon_werk,
maandag = m.maandag,
ma_van = m.ma_van,
ma_tot = m.ma_tot,
dinsdag = m.dinsdag,
di_van = m.di_van,
di_tot = m.di_tot,
woensdag = m.woensdag,
wo_van = m.wo_van,
wo_tot = m.wo_tot,
donderdag = m.donderdag,
do_van = m.do_van,
do_tot = m.do_tot,
vrijdag = m.vrijdag,
vr_van = m.vr_van,
vr_tot = m.vr_tot,
zaterdag = m.zaterdag,
za_van = m.za_van,
za_tot = m.za_tot,
zondag = m.zondag,
zo_van = m.zo_van,
zo_tot = m.zo_tot,
medewerkerID = mm.medewerkerID,
meldingID = mm.meldingID,
datum_van = mm.datum_van,
datum_tot = mm.datum_tot,
MM_ID = mm.ID
};
Debug.WriteLine("Debug testQuery" + testQuery);
var getQueryResult = testQuery.ToList();
Debug.WriteLine("Debug getQueryResult: " + getQueryResult);
var resultDictionary = getQueryResult.GroupBy(x => x.ID).ToDictionary(y => y.Key, z => z.ToList());
Debug.WriteLine("resultDictionary: " + resultDictionary);
var firstItem = resultDictionary.Values.First();
Debug.WriteLine("FirstItem: " + firstItem);
var Entity = new newEntity
{
//ID = firstItem.ID,
ID = firstItem.Select(x => x.ID).First(),
roepnaam = firstItem.Select(x => x.roepnaam).First(),
voorvoegsel = firstItem.Select(x => x.voorvoegsel).First(),
achternaam = firstItem.Select(x => x.achternaam).First(),
tussenvoegsel = firstItem.Select(x => x.tussenvoegsel).First(),
meisjesnaam = firstItem.Select(x => x.meisjesnaam).First(),
datum_in_dienst = firstItem.Select(x => x.datum_in_dienst).First(),
datum_uit_dienst = firstItem.Select(x => x.datum_uit_dienst).First(),
aantal_km_woon_werk = firstItem.Select(x => x.aantal_km_woon_werk).First(),
maandag = firstItem.Select(x => x.maandag).First(),
ma_van = firstItem.Select(x => x.ma_van).First(),
ma_tot = firstItem.Select(x => x.ma_tot).First(),
dinsdag = firstItem.Select(x => x.dinsdag).First(),
di_van = firstItem.Select(x => x.di_van).First(),
di_tot = firstItem.Select(x => x.di_tot).First(),
woensdag = firstItem.Select(x => x.woensdag).First(),
wo_van = firstItem.Select(x => x.wo_van).First(),
wo_tot = firstItem.Select(x => x.wo_tot).First(),
donderdag = firstItem.Select(x => x.donderdag).First(),
do_van = firstItem.Select(x => x.do_van).First(),
do_tot = firstItem.Select(x => x.do_tot).First(),
vrijdag = firstItem.Select(x => x.vrijdag).First(),
vr_van = firstItem.Select(x => x.vr_van).First(),
vr_tot = firstItem.Select(x => x.vr_tot).First(),
zaterdag = firstItem.Select(x => x.zaterdag).First(),
za_van = firstItem.Select(x => x.za_van).First(),
za_tot = firstItem.Select(x => x.za_tot).First(),
zondag = firstItem.Select(x => x.zondag).First(),
zo_van = firstItem.Select(x => x.zo_van).First(),
zo_tot = firstItem.Select(x => x.zo_tot).First()
};
Debug.WriteLine("Entity: " + Entity);
var plainValues = resultDictionary.Values.SelectMany(x => x).ToList();
var resultSchedule = plainValues.Select(x => new medewerker_melding
{
medewerkerID = x.medewerkerID,
meldingID = x.meldingID,
datum_van = x.datum_van,
datum_tot = x.datum_tot,
ID = x.MM_ID
}).ToList();
Entity.medewerker_melding = resultSchedule;
}
You need to check whether MedewerkerMeldingContext dbC = new MedewerkerMeldingContext(); is implementing IEnumerable<T> else, you will not be able to preform the desired action on the table.
This kind of error (Could not find an implementation of the query
pattern) usually occurs when:
You are missing LINQ namespace usage (using System.Linq)
Typeyou are querying does not implement IEnumerable<T>
What i'd recommend, first check the namespace.
Second check for the IEnumerable<T> implementation.
Your query is good enough, you take the context and perform the linq, no issue here. It is 90% that you forgot the namespace since context is already implementing the IEnumerable<T> interface.

Where is the mistake? Group by, join , select .net

I donĀ“t know where is the mistake why it says that does not contain a defintion of ImporteSolicitado, interesesDemora and importeReintegro when they are colums of c and the last one of d
var importes = (from c in _context.ReintegroSolicitado
join d in _context.ReintegroRecibido on c.Expediente.ID equals d.Expediente.ID
group new {c,d} by new { c.Expediente.Codigo} into cd
select new { ImporteSolictadoFinal = cd.Sum(b => b.ImporteSolicitado + b.InteresesDemora), ImporteReintegroFinal = cd.Sum(e => e.ImporteReintegro) });
your group element contains two property c and d. So you need refer to
this property as
...
select new {
ImporteSolictadoFinal = cd.Sum(b => b.c.ImporteSolicitado + b.c.InteresesDemora),
ImporteReintegroFinal = cd.Sum(e => e.d.ImporteReintegro) }
...
This is very tough to get right with query posted. I did my best, but it is probably not exactly correct.
var importes = (from c in _context.reintegroSolicitado
join d in _context.reintegroRecibido on c.expediente.ID equals d.expediente.ID
select new { reintegroSolicitado = c, reintegroRecibido = c})
.GroupBy(x => new { c = x.reintegroSolicitado , d = x.reintegroRecibido})
.Select(cd => new { ImporteSolictadoFinal = cd.Sum(b => b.reintegroSolicitado.ImporteSolicitado + b.reintegroSolicitado.InteresesDemora), ImporteReintegroFinal = cd.Sum(e => e.reintegroRecibido.ImporteReintegro) });
}
}
public class Context
{
public List<ReintegroSolicitado> reintegroSolicitado { get; set; }
public List<ReintegroSolicitado> reintegroRecibido { get; set; }
public Expediente expediente { get; set; }
}
public class ReintegroSolicitado
{
public Expediente expediente { get; set; }
public int ImporteSolicitado { get; set; }
public int InteresesDemora { get; set; }
public int ImporteReintegro { get; set; }
}
public class Expediente
{
public int ID { get; set; }
public int Codigo { get; set; }
}

How can I create set contain id record in first set equal id record in second set?

In database I have two tables:
public partial class PersonOne
{
public int id { get; set; }
public string name { get; set; }
public string surname { get; set; }
}
public partial class PersonTwo
{
public int id { get; set; }
public string firstname { get; set; }
public string lastname { get; set; }
}
I would like to fill my set:
public class PersonOnePersonTwo
{
public int PersonOneId { get; set; }
public int PersonTwoId { get; set; }
}
where PersonOne.name == PersonTwo.firstname && PersonOne.surname == PersonTwo.lastname but I have no idea how I can do that - because below code isn't efficient and is so slow:
List<PersonOne> personOneList = new List<PersonOne>();
List<PersonTwo> personTwoList = new List<PersonTwo>();
List<PersonOnePersonTwo> personOnePersonTwoList = new List<PersonOnePersonTwo>();
foreach (PersonOne personOne in personOneList)
{
foreach(PersonTwo personTwo in personTwoList.Where(x => x.firstname == personOne.name && x.lastname == personOne.surname).ToList())
{
personOnePersonTwoList.Add(new PersonOnePersonTwo
{
PersonOneId = personOne.id,
PersonTwoId = personTwo.id
});
}
};
Try this:
var result = personOneList.Join
(
personTwoList,
person1 => new { Key1 = person1.Name, Key2 = person1.Surname },
person2 => new { Key1 = person2.FirstName, Key2 = person2.LastName },
(person1, person2) => new PersonOnePersonTwo { PersonOneId = person1.Id, PersonTwoId = person2.Id }
).ToList();
I would go with:
var personOnePersonTwoList = new List<PersonOnePersonTwo>();
foreach (var personOne in personOneList)
{
personOnePersonTwoList = personTwoList.Where(x => x.firstname.Equals(personOne.name, StringComparison.OrdinalIgnoreCase) &&
x.lastname.Equals(personOne.surname, StringComparison.OrdinalIgnoreCase))
.Select(x => new PersonOnePersonTwo {PersonOneId = personOne.id, PersonTwoId = x.id}).ToList();
};
As a side note: it's more convinient to use Equals when comparing strings.

Categories

Resources