C# LINQ Statement for the Below Scenario - c#

I am trying to build a LINQ Statement for Joining the below two list in C#.
List1:
FormID FormRound
2 1
2 2
2 3
3 1
4 2
List2:
FormID FormRound Category Date
2 1 Test1 23-Aug
2 1 Test2 24-Aug
2 1 Test3 25-Aug
2 2 Test1 26-Aug
2 2 Test3 27-Aug
3 1 Test1 28-Aug
3 1 Test2 29-Aug
3 1 Test3 30-Aug
I should get the Output as below.
FormID FormRound Test1Date Test2Date Test3Date
2 1 23-Aug 24-Aug Test3
2 2 26-Aug NA 27-Aug
3 3 28-Aug 29-Aug NA
Can anyone please help me in Framing the LINQ Statement?

This LINQ query might look like:
var results = (from a in list1
join b in list2 on new { a.FormId, a.FormRound } equals new { b.FormId, b.FormRound }
group b by new { a.FormId, a.FormRound } into c
select new
{
c.Key.FormId,
c.Key.FormRound,
Test1Date = c.Where(d => d.Category == "Test1").Select(e => e.Date).FirstOrDefault(),
Test2Date = c.Where(d => d.Category == "Test2").Select(e => e.Date).FirstOrDefault(),
Test3Date = c.Where(d => d.Category == "Test3").Select(e => e.Date).FirstOrDefault(),
});
Which, using your sample data, produces:
2 1 23-Aug 24-Aug 25-Aug
2 2 26-Aug null 27-Aug
3 1 28-Aug 29-Aug 30-Aug
This is not exactly your expected results, but I think you have some issues with what you're expecting based on my comments on your question.

Related

Linq Group by to column [duplicate]

This question already has answers here:
Is it possible to Pivot data using LINQ?
(7 answers)
Closed 5 years ago.
I have a list of items with a property code and I want to group by eventId and create a table representation where code values are transformed to columns.
Every triple (event, code,amount) is unique.
I want to transform this
eventId code amount
1 A 100
1 B 101
1 C 102
2 A 103
2 C 104
3 B 105
....
to this
eventId A B C
1 100 101 102
2 103 0 104
3 0 105 0
...
var table=from x in list
group x by x.eventId into gr
select new
{
eventId=gr.Key,
....
}
You need to filter on grouped result and project in to anonymous object :
var table=from x in list
group x by x.eventId into gr
select new
{
eventId=gr.Key,
A = gr.Where(x=>x.code == "A").Sum(x=>x.amount),
B = gr.Where(x=>x.code == "B").Sum(x=>x.amount),
C = gr.Where(x=>x.code == "C").Sum(x=>x.amount)
}
It's actually quite neat to use a lookup:
var table =
from x in list
group x by x.eventId into gr
let lookup = gr.ToLookup(y => y.code, y => y.amount)
select new
{
eventId = gr.Key,
A = lookup["A"].Sum(),
B = lookup["B"].Sum(),
C = lookup["C"].Sum(),
};
I get this result:

max amount of same item in a list with C#

Let's say I have this list:
1
1
1
1
2
2
2
3
I want to narrow it down with C# to a list with a maximum of two same items in a list so it would look like this:
1
1
2
2
3
I used to use 'distinct' like this:
string[] array = System.IO.File.ReadAllLines(#"C:\list.txt");
List<string> list = new List<string>(array);
List<string> distinct = list.Distinct().ToList();
but don't have an idea on how it could bring a max number of same values
You could do it with Linq as follows.
var Groups = Input.GroupBy( i => i );
var Result = Groups.SelectMany( iGroup => iGroup.Take(2) ).ToArray();

How to use Distinct for this select query in LINQ [duplicate]

This question already has answers here:
LINQ: Distinct values
(8 answers)
Closed 8 years ago.
I have following query:
var query = from product in SH_Products
from product_group in SH_ProductGroups_Products.Where(c=>c.ProductID == product.ID)
from manufacturer in SH_Manufacturers.Where(c=>c.ID == product.ManufactureID)
from attributeOption_product in SH_AttributeOptions_Products.Where(c=>c.ProductID == product.ID).DefaultIfEmpty()
where !product.IsDeleted
&& !product_group.IsDeleted
&& !manufacturer.IsDeleted
&& product.Status != 0
select new
{
product.ID,
ProductGroupID = product_group.ProductGroupID,
AttributeOptionID = (int?)attributeOption_product.AttributeOptionsID,
product.ManufacturerID
};
query.Distinct().Dump();
Below is the sample output:
ID ProductGroupID AttributeOptionID ManufacturerID
1 1 75 1
1 1 76 1
2 3 17 2
3 2 3 1
4 1 NULL 1
As you see, we have 2 record with ID = 1, and I don't wanna this, how I can remove this one?
I wrote this query for filtering section of my project.
I have filtering by ProductGroupID, AttributeOptionID, ManufacturerID, all of them are multi-select-able !
thanks !
As I said in the comments, you can use the other overload of Distinct extension method which asks for an EqualityComparer.
Or another way you can use
query.GroupBy(item => item.ID).Select(grp => grp.First())...
instead of
query.Distinct()...
Please do not forget that the output will not contain the second record in your sample output.
If the key of your records is not only ID but ID and ProductGroupID instead, usage can be
query.GroupBy(item => new {item.ID, item.ProductGroupId} ).Select(grp => grp.First())...

entity framework many to many multiple select

I have 3 tables for many to many relationship.
MailLists =>MailListInGroups<=MailGroups
And MailListInGroups table like below;
MLID MGID
2 1
2 3
3 2
3 3
4 1
4 4
5 1
5 5
6 2
6 5
7 2
7 3
My MailGroups Table below;
MGID
1 Türkiye
2 İtalya
3 Çok İyi
4 İyi
5 Orta
And My MailLists Table below;
MLID
2 xxx#hotmail.com NULL NULL
3 yyy#hotmail.com NULL NULL
4 zzz#hotmail.com NULL NULL
5 ppp#hotmail.com NULL NULL
6 trp#deneme.com NULL NULL
7 zzz#hotmail.com NULL NULL
I need fetch to MailGroupID just 2 and 3. And My action below;
for example int[] ints= 2,3
public ActionResult SelectGroup(int[] ints)
{
var mails = new List<MailList>();
var groups = ints.Select(item => _bb.MailGroups.Include("MailLists").Where(m => m.MailGroupID == item)).ToList();
}
Groups select all include MailGroupID's 2 and 3 rows.(MLID=2,3,6,7). But I need just 2 rows.(MLID=3,7) How can select just 2 MLID?
Try this
public ActionResult SelectGroup(int[] ints)
{
var listToFilter = new HashSet<int>(ints);
var list = _bb.MailGroups.Where(m => listToFilter.Contains(m.ID))
.SelectMany(m => m.MailLists);
}
Update :
I think that u need to change your method to be like this :
public ActionResult SelectGroup(int[] mailGroupIds, int[] mailListIds)
{
var list = _bb.MailGroups.Where(m => mailGroupIds.Contains(m.ID))
.SelectMany(m => m.MailLists)
.Where(l => mailListIds.Contains(l.ID));
}

C# LINQ Query

I have the following query:
var results = from theData in GeometricAverage
group theData by new { study = theData.study, groupNumber = theData.groupNumber, GeoAverage= theData.GeoAverage } into grp
select new
{
study = grp.Key.study,
groupNumber = grp.Key.groupNumber,
TGI = testFunction(grp.Key.GeoAverage, Also here I want to pass in the GeoAverage for only group 1 (but for each individual study))
};
What I want to do is that for each study, there are multiple groups with a GeoAverage figure for each group. The TGI is calculated by passing the GeoAverage figure for each group and the GeoAverage figure for group 1 (on each study) into the testFunction. I can't figure out how to pass in the value just for group 1.
Hope this makes sense.
EDIT: Sample of data:
Study Group GeoAverage
1 1 3
1 2 5
1 3 6
2 1 2
2 2 3
2 3 9
So, for the above data, I would want each GeoAverage figure for each group, to be evaluated against the GeoAverage figure of group 1 within that same study. So if I have say a function:
int foo(int a, int b)
{
return a * b;
}
Using the data above, I would first evaluate study 1, group 1 against itself, so pass in GeoAverage 3 twice and return 9. For Study 1, group 2, pass in group 2 GA at 5, and that studys group1 GA at 3, returning 15.
Have now worked it out. I iterate through a collection of data that I want the value to be stored against and use the following two LINQ queries:
foreach (var data in compoundData)
{
var controlValue = from d in GeometricAverage
where d.study == data.study
where d.groupNumber == "1"
select d.GeoAverage;
var treatmentValue = from l in GeometricAverage
where l.study == data.study
where l.groupNumber == data.groupNumber
select l.GeoAverage;
data.TGI = CalculateTGI(controlValue, treatmentValue);
}

Categories