I have an object like as shown below
public class SampleObject
{
public int MsfId { get; set; }
public List<string> PgId { get; set; }
public List<string> DcId { get; set; }
}
In the above aggregation of the PgId
values grouped by MsfId
. Same is the case with DcId
as well.
For example:
MsfId: 100
PgId: "abc"
DcId: "123"
MsfId: 100
PgId: "def"
DcId: "456"
MsfId: 100
PgId: "ghi"
DcId: "789"
MsfId: 101
PgId: "abc"
DcId: "123"
How to write a LINQ query to aggregate this and create a list of SampleObjects like below?
MsfId: 100
PgId: "abc", "def", "ghi"
DcId: "123", "456", "789"
MsfId: 101
PgId: "abc"
DcId: "123"
Try aggregation like this:
var result = col.GroupBy(x => x.MsfId)
.Select(x => new SampleObject {
MsfId = x.Key,
PgCodes = x.Select(t=>t.PgId).ToList(),
DcCodes = x.Select(t=>t.DcId).ToList()
});
Scenario 1
public class SampleObject
{
public int MsfId { get; set; }
public List<string> PgId { get; set; }
public List<string> DcId { get; set; }
}
Scenario 2
public class SampleObjectSource
{
public int MsfId { get; set; }
public string PgId { get; set; }
public string DcId { get; set; }
}
Scenario 1 Answer
var collection = new List<SampleObject>();
var result = collection.GroupBy(y => y.MsfId)
.Select(y => new SampleObject
{
MsfId = y.Key,
PgId = y.SelectMany(g => g.PgId).Distinct().ToList(),
}).ToList();
Scenario 2
var collection2 = new List<SampleObjectSource>();
var result1 = collection2.GroupBy(y => y.MsfId)
.Select(y => new SampleObject
{
MsfId = y.Key,
PgId = y.Select(h => h.PgId).Distinct().ToList(),
}).ToList();
Update : Please see the dotnetfiddle
You need to group the items with a query. This linq grouping will create a collection of collections(with a key)
I just made a full working example:
// The class to start with
public class SampleObjectSource
{
public int MsfId { get; set; }
public string PgId { get; set; }
public string DcId { get; set; }
}
// the result class
public class SampleObject
{
public int MsfId { get; set; }
public List<string> PgId { get; set; }
public List<string> DcId { get; set; }
}
// for example:
public class Example
{
public Example()
{
// create a list that contains the items.
var list = new List<SampleObjectSource>
{
new SampleObjectSource { MsfId= 100, PgId= "abc", DcId= "123" },
new SampleObjectSource { MsfId= 100, PgId= "def", DcId= "456" },
new SampleObjectSource { MsfId= 100, PgId= "ghi", DcId= "789" },
new SampleObjectSource { MsfId= 101, PgId= "abc", DcId= "123" },
};
// the linq query that does the grouping.
var query = from item in list
// group the items by MsfId
group item by item.MsfId into itemgroup
// create the new class and initialize the properties
select new SampleObject
{
// the grouping item is the .Key (in this case MsfId)
MsfId = itemgroup.Key,
// the itemgroup is a collection of all grouped items, so you need to select the properties you're interrested in.
DcId = itemgroup.Select(i => i.DcId).ToList(),
PgId = itemgroup.Select(i => i.PgId).ToList()
};
// show the results in the Output window.
foreach (var item in query)
{
Trace.WriteLine($"MsfId: {item.MsfId}");
// some trick to format a list of strings to one string
Trace.WriteLine($"PgId: {string.Join(", ", item.PgId.Select(s => Quote(s)))}");
Trace.WriteLine($"DcId: {string.Join(", ", item.DcId.Select(s => Quote(s)))}");
Trace.WriteLine("");
}
}
// this method will surround the passed string with quotes.
private string Quote(string item)
{
return "\"" + item + "\"";
}
}
results:
MsfId: 100
PgId: "abc", "def", "ghi"
DcId: "123", "456", "789"
MsfId: 101
PgId: "abc"
DcId: "123"
Do it all with one GroupBy
using the appropriate overload. Working Fiddle Here.
Note the use of SelectMany
to concatenate the grouped collections into one.
var result = sampleObjects
.GroupBy(
o => o.MsfId,
(k, g) => new SampleObject
{
MsfId = k,
PgId = g.SelectMany(p => p.PgId).ToList(),
DcId = g.SelectMany(p => p.DcId).ToList()
});
If you want to remove duplicates from the collections consider Distinct()
e.g.
var result = sampleObjects
.GroupBy(
o => o.MsfId,
(k, g) => new SampleObject
{
MsfId = k,
PgId = g.SelectMany(p => p.PgId).Distinct().ToList(),
DcId = g.SelectMany(p => p.DcId).Distinct().ToList()
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With