How to avoid Looping and refactor the Code in C# - c#

My use case is, I have a List of orders that I need to post to external API.
but the conditions are that, I can post 5 order in one post call of API.
and these 5 orders have to be of same store and of deliveryWindows should be either morning or afternoon for all 5 orders.
I have written the below code but I am not happy with that, Can anyone Kindly help to refactor the below logic.
I have used 3 for loops to Loop through Deliverywindow and also for stores and for all the orders in the store.
Is there better approach/async Looping of the below/ having separate method calls.
Any suggestion is really helpful!
using MoreLinq;
using System;
using System.Collections.Generic;
using System.Linq;
static void Main(string[] args)
{
//In real time I will have 1000's of orders for one store and deliveryWindow (Morning)
var allOrders = GetProductOrders();
string[] deliveryWindows = new[] { "Morning", "AfterNoon" };
//Looping for Morning & Afternoon
foreach (var deliveryWindow in deliveryWindows)
{
//Getting Morning order in first run and afternoon order in second run
var OrderForWindow = allOrders.Where(x => x.DeliveryWindow.Equals(deliveryWindow));
//Getting All Unique Store (Will have StoreA, StoreB, etc)
List<string> Stores = OrderForWindow.Select(x => x.StoreName).Distinct().ToList();
foreach (var Store in Stores)
{
//Store releated order for that windown (morning/afternoon)
var StoreOrders = OrderForWindow.Where(order => order.StoreName.Equals(Store)).ToList();
//taking 10 items from StoreOrders
//Batch will pick 5 items at once
foreach (var orders in StoreOrders.Batch(5))
{
//storeOrder will have list of 5 order which all have same delivery window
//Post External call
}
}
}
}
public static List<ProductOrder> GetProductOrders()
{
List<ProductOrder> productOrder = new List<ProductOrder>()
{
new ProductOrder(){ ID = 1, DeliveryWindow ="Morning", StoreName = "StoreA", customerDetails = "Cust1"},
new ProductOrder(){ ID = 2, DeliveryWindow ="Morning", StoreName = "StoreA",customerDetails = "Cust2"},
new ProductOrder(){ ID = 3, DeliveryWindow ="Morning", StoreName = "StoreA",customerDetails = "Cust3"},
new ProductOrder(){ ID = 4, DeliveryWindow ="AfterNoon", StoreName = "StoreA",customerDetails = "Cust4"},
new ProductOrder(){ ID = 5, DeliveryWindow ="AfterNoon", StoreName = "StoreA",customerDetails = "Cust5"},
new ProductOrder(){ ID = 6, DeliveryWindow ="Morning", StoreName = "StoreB",customerDetails = "Cust6"},
new ProductOrder(){ ID = 7, DeliveryWindow ="Morning", StoreName = "StoreB",customerDetails = "Cust7"},
new ProductOrder(){ ID = 8, DeliveryWindow ="AfterNoon", StoreName = "StoreB",customerDetails = "Cust8"},
new ProductOrder(){ ID = 9, DeliveryWindow ="AfterNoon", StoreName = "StoreB",customerDetails = "Cust9"},
new ProductOrder(){ ID = 10, DeliveryWindow ="AfterNoon", StoreName = "StoreC",customerDetails = "Cust10"},
};
return productOrder;
}
}
public class ProductOrder
{
public int ID { set; get; }
public string StoreName { set;get;}
public string DeliveryWindow { set; get; }
public string customerDetails { set; get; }
public string ProductDetails { set; get; }
}

As pointed out, this post is a great resource to help you understand how to group against multiple keys.
Here's what that would look like in your case:
var allOrders = GetProductOrders();
var groupedOrders = from order in allOrders
// We group using an anonymous object
// that contains the properties we're interested in
group order by new
{
order.StoreName,
order.DeliveryWindow
};
// Access is straightforward:
foreach (var orderGroup in groupedOrders)
{
Console.WriteLine($"Group {orderGroup.Key.StoreName} {orderGroup.Key.DeliveryWindow}");
// The group is a list itself, so you can apply
// your Batch LINQ extension
foreach (var order in orderGroup)
{
Console.WriteLine(order.ID);
}
}

Related

LINQ to get unique id that has list of items

I am trying to generate a list result through linq.
I would like to have a result as a list with unique folder id with 0th item as folder_name, 1st Item as a list with one or more projects having fields project_id,name and description.
I have written following query:
Folders is basically model with format as folderid, name, List projects where Project Model has project_id, name and description
from the following records:
Models
public class FolderModel
{
public int folder_id { get; set; }
public string folder_name { get; set; }
public List<ProjectModel> projects{ get; set; }
}
public class ProjectModel
{
public int project_id { get; set; }
public string project_name { get; set; }
public string project_description { get; set; }
}
public class ResultModel
{
public List<FolderModel> folders { get; set; }
}
Result Data
List<FolderModel, List<ProjectModel>> result = new List<FolderModel, List<ProjectModel>>();
List<ProjectModel> projectList1 = new List<>();
ProjectModel projectModel1 = new ProjectModel();
projectModel1.project_name = "F1P1";
projectModel1.project_description = "F1P1";
projectList1.add(projectModel1);
List<ProjectModel> projectList2 = new List<>();
ProjectModel projectModel21 = new ProjectModel();
projectModel21.project_name = "F2P1";
projectModel21.project_description = "F2P1";
projectList2.add(projectModel21);
ProjectModel projectModel22 = new ProjectModel();
projectModel22.project_name = "F2P2";
projectModel22.project_description = "F2P2";
projectList2.add(projectModel22);
List<ProjectModel> projectList3 = new List<>();
ProjectModel projectModel3 = new ProjectModel();
projectModel3.project_name = "F3P1";
projectModel3.project_description = "F1P3";
projectList3.add(projectModel3);
ResultModel resultModel = new resultModel();
resultModel.(new FolderModel { folder_id: 1,folder-name: "F1" }, projectList1);
FolderModel folderModel1 = new FolderModel();
folderModel1.folder_id = 1
folderModel1.folder_name = "F1"
folderModel1.projects = projectList1
FolderModel folderModel2 = new FolderModel();
folderModel2.folder_id = 2
folderModel2.folder_name = "F2"
folderModel2.projects = projectList2
FolderModel folderModel3 = new FolderModel();
folderModel3.folder_id = 3
folderModel3.folder_name = "F3"
folderModel3.projects = projectList3
ResultModel resultModel = new ResultModel();
List<FolderModel> folderList = new List<>();
folderList.add(folderModel1);
folderList.add(folderModel2);
folderList.add(folderModel3);
resultModel.folders = folderList
SQL Data
folder_id | folder_name | project_id | project_name | project_description
1 F1 11 F1P1 F1P1
2 F2 21 F2P1 F2P1
2 F2 22 F2P2 F2P2
3 F3 31 F3P1 F3P1
4 F4 41 F4P1 F4P1
5 F5 51 F5P1 F5P1
This is what I have tried
var result = resultModel.folders.GroupBy(x => new { x.folder_id }).ToList();
I am sure that after group by I have to select name but not sure how can I generate project into a list and add it to main folder id. Can someone please guide on this.
You can query like this:
var result =
resultModel
.folders
.GroupBy(x => new { x.folder_id })
.Select(s => new
{
folder_id = s.Key,
folder_name = s.First().folder_name
})
.ToList();
It seems to me that you're looking for this:
var folders = new []
{
new { folder_id = 1, folder_name = "F1", project_id = 11, project_name = "F1P1", project_description = "F1P1" },
new { folder_id = 2, folder_name = "F2", project_id = 21, project_name = "F2P1", project_description = "F2P1" },
new { folder_id = 2, folder_name = "F2", project_id = 22, project_name = "F2P2", project_description = "F2P2" },
new { folder_id = 3, folder_name = "F3", project_id = 31, project_name = "F3P1", project_description = "F3P1" },
new { folder_id = 4, folder_name = "F4", project_id = 41, project_name = "F4P1", project_description = "F4P1" },
new { folder_id = 5, folder_name = "F5", project_id = 51, project_name = "F5P1", project_description = "F5P1" },
};
List<FolderModel> result =
folders
.GroupBy(
x => new { x.folder_id, x.folder_name },
x => new { x.project_id, x.project_name, x.project_description })
.Select(x => new FolderModel()
{
folder_id = x.Key.folder_id,
folder_name = x.Key.folder_name,
projects = x.Select(y => new ProjectModel()
{
project_id = y.project_id,
project_name = y.project_name,
project_description = y.project_description,
}).ToList(),
})
.ToList();

Grouping not working as expected returning more emails than should

I have a sales order table with 23 transaction they are assigned to either department 1 or 2 I have looked at the data and its has the right assigns to it based on the cateory name however the problem is in my exucuation of the loop as I am getting 23 emails instead of just 5 sales order emails which is what it should be
Say for Example The table is
SalesOrder Number Depart
1111 1
1111 2
2222 2
2222 2
I should be getting one email for sales order 1111 sent to department 1 and one sent to department 2 but in the 2222 case I should get one email including all 2222
I think the issue is the group by does not no how to batch and I am asking what is the best way of doing that.
public void ProcessTransactions(string csvFileName)
{
var engine = new FileHelperEngine<SalesOrderHeader>();
var SalesOrders = engine.ReadFile(csvFileName);
var engine2 = new FileHelperEngine<SalesOrdersLines>();
var OrderLines = engine2.ReadFile(csvFileName);
GetSalesOrdersForImport();
ImportTransActions(SalesOrders.ToList());
CreateSalesOrder(_salesOrders.ToList(), _salesOrders.ToList());
var groupedSalesOrders = SalesOrders.OrderBy(x => x.SalesOrderNumber)
.GroupBy(x => x.SalesOrderNumber);
foreach(var group in groupedSalesOrders)
{
foreach (var item in group)
{
GetEmailsFromDepartment(item.DepartmentId);
GetSalesOrdersByDepartment(item.DepartmentId);
SendEmailNotificationPerDepartments(item.SalesOrderNumber.ToString());
}
}
}
My Get Emails for Department function is as below
public List<EmailDepartMents> _emailListsByDepartment { get; set; }
public void GetEmailsFromDepartment(string departmentId )
{
string connectionString = ConfigurationManager.AppSettings["connectionString"];
using (var connection = new SqlConnection(connectionString))
{
connection.Open();
string selectQuery = #"SELECT [Code]
,[Name]
,[U_DepartmentId] AS DepartmentId
,[U_CardCode] as CardCode
,[U_Email] As Email
FROM [NKCoatings].[dbo].[#FIT_DEPARTMENTS]
where [U_DepartmentId]='" + departmentId +"'";
_emailListsByDepartment = connection.Query<EmailDepartMents>(selectQuery).ToList();
}
}
}
Edit 2
To Show send email function in case there is a issue with it in it self.
public void SendEmailNotificationPerDepartments(List SalesOrders)
{
try
{
SAPbobsCOM.UserTable sboTable = (SAPbobsCOM.UserTable)company.UserTables.Item("DEPARTMENTS");
SAPbobsCOM.BusinessPartners sboBP = (SAPbobsCOM.BusinessPartners)company.GetBusinessObject(SAPbobsCOM.BoObjectTypes.oBusinessPartners);
string emailAddressCC = ConfigurationManager.AppSettings["EmailAddressTo"];
string body;
string stmpServer = ConfigurationManager.AppSettings["SmtpAddress"];
string EmailUserName = ConfigurationManager.AppSettings["EmailUserName"];
string EmailPassword = ConfigurationManager.AppSettings["EmailPassword"];
string SmtpPort = ConfigurationManager.AppSettings["SmtpPort"];
MailMessage Msg = new MailMessage();
Msg.From = new MailAddress("development#test.com");
Msg.IsBodyHtml = true;
Msg.Subject = "Sales Orders Created in SAP";
body = "Sales orders has been imported into sap";
StringBuilder sb = new StringBuilder();
using (Html.Table table = new Html.Table(sb, id: "some-id"))
{
table.StartHead();
using (var thead = table.AddRow())
{
thead.AddCell("Works Order Number");
thead.AddCell("Purchase Order Number");
thead.AddCell("Date Required");
thead.AddCell("Stock Item Code");
thead.AddCell("Stock Item Name");
thead.AddCell("Customer");
}
table.EndHead();
table.StartBody();
foreach (var order in SalesOrders.Where(w=>w.DepartmentId == DepartmentId && w.SalesOrderNumber ==salesOrderId).OrderBy(o=>o.SalesOrderNumber))
{
using (var tr = table.AddRow(classAttributes: "someattributes"))
{
tr.AddCell(order.WorksOrderNumber, "style:font-bold;");
tr.AddCell(order.PurchaseOrderNumber.ToString());
tr.AddCell(order.DateRequired.ToString());
tr.AddCell(order.ItemCode.ToString());
tr.AddCell(order.Description.ToString());
if(sboBP.GetByKey(order.CardCode))
{
sboBP.CardName.ToString();
}
}
}
}
foreach (var address in _emailListsByDepartment)
{
Msg.To.Add(address.Email);
}
foreach (var address in emailAddressCC.Split(new[] { ";" }, StringSplitOptions.RemoveEmptyEntries))
{
Msg.CC.Add(address);
}
body = body + Environment.NewLine + sb.ToString();
Msg.Body = body;
SmtpClient smtp = new SmtpClient(stmpServer);
smtp.Credentials = new NetworkCredential(EmailUserName, EmailPassword);
smtp.Host = stmpServer;
smtp.Port = Convert.ToInt16(SmtpPort);
smtp.Send(Msg);
}
catch (Exception ex)
{
log.Error("Error has occoured at the send email notification " + ex.ToString());
}
}
I think i am just having a saturday night black out here but I hope someone can help me out maybe I am doing something wrong.
It could look something like this:
var list = new List<Email>()
{
new Email() {SalesOrderNumber = 10, Depart = 1},
new Email() {SalesOrderNumber = 10, Depart = 2},
new Email() {SalesOrderNumber = 20, Depart = 2},
new Email() {SalesOrderNumber = 20, Depart = 2},
};
var groups = list.GroupBy(e => e.SalesOrderNumber) // sort all emails by SalesOrderNumber
.Select(g => g.GroupBy(e => e.Depart)) // sort groups by Depart
.Aggregate((l, r) => l.Concat(r)); // aggregate result to only one collection of groups
foreach (var group in groups)
{
Console.WriteLine($"Group of SalesOrderNumber: {group.First().SalesOrderNumber}, Depart: {group.Key}");
foreach (var email in group)
{
Console.WriteLine(email);
}
}

How to write a DISTINCT or GROUPBY LINQ statement using a strongly typed model in MVC

I have a Model called Survey as highlighted below;
I want to write a LINQ statement in my controller that will query the Survey Table and return distinct records by 'Topic'. Each distinct record will have an average rating. For example;
I'm new to LINQ and have a hard time when creating anything that is not basic.
My attempt;
var results = from s in db.Surveys
where s.Topic.Distinct()
select new Survey
{
SurveyId = s.SurveyId,
Category = s.Category.Name,
Topic = s.Topic,
Store1Rating= db.Surveys.Average(s => s.Score1).Value,
Store2Rating= db.Surveys.Average(s => s.Score2).Value
};
Thanks for your help in advance!
Try this
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
var survey1 = new Survey() { Topic = "topic1", Store1Rate = 5, Store2Rate = 4 };
var survey2 = new Survey { Topic = "topic2", Store1Rate = 6, Store2Rate = 2 };
var survey3 = new Survey { Topic = "topic2", Store1Rate = 7, Store2Rate = 2 };
var survey4 = new Survey { Topic = "topic3", Store1Rate = 6, Store2Rate = 4 };
var survey5 = new Survey { Topic = "topic3", Store1Rate = 1, Store2Rate = 2 };
var survey6 = new Survey { Topic = "topic3", Store1Rate = 2, Store2Rate = 9 };
List<Survey> surveys = new List<Survey>() { survey1, survey2, survey3, survey4, survey5, survey6 };
var result = surveys.GroupBy(s => s.Topic).Select(s => new { Topic = s.Key, Rate1 = s.Average(a => a.Store1Rate), Rate2 = s.Average(a => a.Store2Rate) });
}
}
class Survey
{
public string Topic;
public int Store1Rate;
public int Store2Rate;
}
}
Dissapointed is correct
If you want to use this as a model you have to cast it to a list for example:
`var result = surveys.GroupBy(s => s.Topic).Select(s => new { Topic = s.Key, Rate1 = s.Average(a => a.Store1Rate), Rate2 = s.Average(a => a.Store2Rate) }).ToList();`
Then in your controller you do a:
`return View("ViewName", result)`

LINQ to Objects filtering

I have a class, BillingProvider, which contains a list of Claims. Separately, I have a list of the claim numbers which contain errors. I want to exclude the claims with errors and, if all the claims under any BillingProvider have errors, then exclude the BillingProvider too. I've created a simplified mock-up of the situation. The LINQ query below excludes the errors but returns the BillingProvider multiple times.
class Program
{
class BillingProvider
{
internal string TaxId { get; set; }
internal List<Claim> Claims = new List<Claim>();
}
class Claim
{
internal int ClaimNumber { get; set; }
internal string ClaimDescr { get; set; }
}
private static void Main()
{
var allBillingProviders = new List<BillingProvider>
{
new BillingProvider
{
TaxId = "123456789",
Claims = new List<Claim>
{
new Claim {ClaimNumber = 1, ClaimDescr = "First Claim"},
new Claim {ClaimNumber = 2, ClaimDescr = "Second Claim"},
new Claim {ClaimNumber = 3, ClaimDescr = "Third Claim"}
}
},
new BillingProvider
{
TaxId = "012345678",
Claims = new List<Claim>
{
new Claim{ClaimNumber = 4, ClaimDescr = "Fourth Claim"},
new Claim{ClaimNumber = 5, ClaimDescr = "Fifth Claim"},
new Claim{ClaimNumber = 6, ClaimDescr = "Sixth Claim"},
new Claim{ClaimNumber = 7, ClaimDescr = "Seventh Claim"},
new Claim{ClaimNumber = 8, ClaimDescr = "Eighth Claim"}
}
}
};
// Set up errors
var errors = new List<int> {2, 5}; // Claims 2 and 5 have erros and should be excluded
var bpClaims = (from b in allBillingProviders
from c in b.Claims
where (!errors.Contains(c.ClaimNumber))
select b).ToList();
foreach (var bpc in bpClaims)
Console.WriteLine("Count of claims in {0} is {1}", bpc.TaxId, bpc.Claims.Count);
Console.ReadLine();
}
}
I would do this in two steps:
var bpClaims =
allBillingProviders.Select(x => new BillingProvider()
{
TaxId = x.TaxId,
Claims = x.Claims.Where(c => !errors.Contains(c.ClaimNumber)).ToList()
})
.Where(x => x.Claims.Any())
.ToList();
One way to use distinct, but since you may want to distinct by ClaimNumber since I think claim number will not be repeated you can use this library that has DistictBy
https://code.google.com/p/morelinq/
var bpClaims = (from b in allBillingProviders
from c in b.Claims
where (!errors.Contains(c.ClaimNumber))
select b).DistinctBy(c=>c.ClaimNumber).ToList();
You can get the count of the claim IDs without including the error claim IDs by doing this in your Console.WriteLine line:
Console.WriteLine("Count of claims in {0} is {1}", bpc.TaxId, bpc.Claims.Select(x=> x.ClaimNumber).ToList().Except(errors).Count());

Grouping Linq Issue, can't get it right

public class Emp
{
public int EmpId { get; set; }
public string Type { get; set; }
public List<string> Email { get; set; }
}
I fetch data from database and put it in a list
List<Emp> employees= new List<Emp>();
// fill the list here via DB call
The list would have, please also note that Type field would always be same for same user but email would be different
employees[0] = new Emp{ EmpId = 1, Type = "User", Email = "one#test.com" };
employees[1] = new Emp{ EmpId = 1, Type= "User", Email = "two#test.com" };
employees[2] = new Emp{ EmpId = 2, Type = "Test", Email = "three#test.com" };
employees[3] = new Emp{ EmpId = 2, Type= "Test", Email = "four#test.com"};
employees[4] = new Emp{ EmpId = 3, Type = "Test", Email = "five#test.com" };
employees[5] = new Emp{ EmpId = 3, Type= "Test", Email = "six#test.com"};
employees[6] = new Emp{ EmpId = 4, Type= "User", Email = "seven#test.com"};
I'm trying to group Emp based on their EmpId
so the result should be a new list
Expected Result
Result = new Emp{ EmpId = 1, Type = "User", Email = "one#test.com", "two#test.com" };
new Emp{ EmpId = 2, Type = "Test", Email = "three#test.com", "four#test.com" };
new Emp{ EmpId = 3, Type = "Test", Email = "five#test.com", "six#test.com" };
new Emp{ EmpId = 4, Type = "User", Email = ""seven#test.com" };
//This is what I have done so far
// Please let me know if this is incorrect
var result = from emp in employees
group emp.Email by new { emp.EmpId, emp.Type } into g
select new { Key = g.Key, Type = g.Key.Type, Emails = g.ToList() };
// My problem comes here when I loop this result
foreach (var r in result)
{
Console.WriteLine(r.Key.EmpId + "--" + r.Key.Type);
//This is where I need to get all emails of the Employee which I grouped
// iF I IMPLEMENT FOREACH
foreach (var e in r.Emails)
{
//?? WHAT i DO HERE
//e.?? to get email
}
// OR iF I IMPLEMENT FOR LOOP
for(int i = 0 ; i< r.Emails.Count; i++)
{
Console.WriteLine("Inner Loop" + "--" + r.Key.EmpId + "--" + r.Key.Type + "--" + r.Emails[0].ToString()); // r.Emails[0].ToString() prints out System.Collections.Generic.List '1[System.String]
}
}
Please let me know if I mad eany mistake or there's other way to do this.
All I need is Group employees based on EmpID and also have their Type but grouped Emails.
Your group emp.Email by new { emp.EmpId, emp.Type } means that each element of the group will have a key of the anonymous type, and an "element type" of List<string>. You're then propagating that element type using Emails = g.ToList() in your select clause. Therefore I'd expect the type of r.Emails to be List<List<string>> (which you should be able to validate in Visual Studio by hovering over r.Emails.
You could handle that in your loop - or you could just flatten it in your select call, creating a new Emp:
select new Emp {
EmpId = g.Key.EmpId,
Type = g.Key.Type,
Emails = g.SelectMany(x => x).ToList()
};
Here the SelectMany call is just flattening the "sequence of lists" to a single sequence.
Maybe a slight change could be usefull: if you change the Email property from a list to string you could group the employees like that:
// Group by EmpId
var group = employees.GroupBy(e => e.EmpId);
and get the list for a single emp like this:
// Example get email List of first emp
group.First().Select(g => g.Email);
You could change your Emp class so that EMail is a string instead of a List<string>.
The foreach loop then becomes
foreach(string e in r.EMails){
//e holds the EMail
//do stuff
}
Try This:-
var query1 = from emp in employees
group emp.Email by new { emp.EmpId, emp.Type } into empgroup
select new
{
UserId = empgroup.Key.EmpId,
EmployeeType = empgroup.Key.Type,
EmaiIds = empgroup.SelectMany(x => x)
};
foreach (var x in query1)
{
Console.WriteLine(x.UserId);
Console.WriteLine(x.EmployeeType);
foreach (var emails in x.EmaiIds)
{
Console.WriteLine(emails);
}
}
void Main()
{
List<Emp> employees= new List<Emp>();
employees.Add(new Emp{ EmpId = 1, Type = "User", Email = "one#test.com" });
employees.Add(new Emp{ EmpId = 1, Type = "User", Email = "two#test.com" });
employees.Add(new Emp{ EmpId = 2, Type = "Test", Email = "three#test.com" });
employees.Add(new Emp{ EmpId = 2, Type = "Test", Email = "four#test.com" });
employees.Add(new Emp{ EmpId = 3, Type = "Test", Email = "five#test.com" });
employees.Add(new Emp{ EmpId = 3, Type = "Test", Email = "six#test.com" });
employees.Add(new Emp{ EmpId = 4, Type = "User", Email = "seven#test.com" });
var groupedList = from emp in employees
group emp.Email by new { emp.EmpId, emp.Type } into g
select new { Key = g.Key, Type = g.Key.Type, Emails = g.ToList() };
foreach (var result in groupedList)
{
//I'm using LINQPad to output the results
result.Key.EmpId.Dump();
foreach(var email in result.Emails)
{
email.Dump();
}
}
}
public class Emp
{
public int EmpId { get; set; }
public string Type { get; set; }
public string Email { get; set; }
}
My results are:
or...
void Main()
{
List<Emp> employees= new List<Emp>();
employees.Add(new Emp{ EmpId = 1, Type = "User", Emails = new List<string>(){"one#test.com"} });
employees.Add(new Emp{ EmpId = 1, Type = "User", Emails = new List<string>(){"two#test.com"} });
employees.Add(new Emp{ EmpId = 2, Type = "Test", Emails = new List<string>(){"three#test.com"} });
employees.Add(new Emp{ EmpId = 2, Type = "Test", Emails = new List<string>(){"four#test.com"} });
employees.Add(new Emp{ EmpId = 3, Type = "Test", Emails = new List<string>(){"five#test.com"} });
employees.Add(new Emp{ EmpId = 3, Type = "Test", Emails = new List<string>(){"six#test.com"} });
employees.Add(new Emp{ EmpId = 4, Type = "User", Emails = new List<string>(){"seven#test.com"} });
var groupedList = from emp in employees
group emp.Emails by new { emp.EmpId, emp.Type } into g
select new Emp {
EmpId = g.Key.EmpId,
Type = g.Key.Type,
Emails = g.SelectMany(x => x).ToList()
};
foreach (var result in groupedList)
{ //I'm using LINQPad to output
result.EmpId.Dump();
result.Emails.ForEach(e => e.Dump());
}
}
public class Emp
{
public int EmpId { get; set; }
public string Type { get; set; }
public List<string> Emails { get; set; }
}
My results are also:

Categories