How to use ORDER BY COUNT in LINQ and SELECT COUNT it? - c#

I have a query and I don't know change it to LINQ
select distinct m.id,m.name, sch.id as schedule, COUNT(tk.id) as tiketSold
from movies m, schedules sch, tickets tk
where m.id = sch.movie_id and sch.id = tk.schedule_id
group by m.id,m.name, sch.id
order by COUNT(tk.id) desc
I'm trying:
var hotMovie = from m in _db.movies
from sch in _db.schedules
from tk in _db.tickets
where m.id == sch.movie_id && sch.id == tk.schedule_id
group m by m.id into g
orderby g.Count()
select new { Movie = g};

I do not have your database, so, I have created 3 classes like your table as I can anticipate. Then I have created 3 list like you table in the "TestMethod". In the linq query, I have joined the 3 list as you shown in sql query segment "where m.id = sch.movie_id and sch.id = tk.schedule_id" and then I perform the group by, order by an select. Here is my code, please try it and let me know it works or not.
public class movies
{
public int id { get; set; }
public string name { get; set; }
}
public class schedules
{
public int id { get; set; }
public int movie_id { get; set; }
}
public class tickets
{
public int id { get; set; }
public int schedule_id { get; set; }
}
void TestMethod()
{
//Add Movies to the list
List<movies> moviesItems = new List<movies>();
moviesItems.Add(new movies() { id = 1, name = "A" });
moviesItems.Add(new movies() { id = 2, name = "B" });
//Add Schedules to the list
List<schedules> schedulesItems = new List<schedules>();
schedulesItems.Add(new schedules() { id = 1, movie_id = 1 });
schedulesItems.Add(new schedules() { id = 2, movie_id = 2 });
schedulesItems.Add(new schedules() { id = 3, movie_id = 1 });
schedulesItems.Add(new schedules() { id = 4, movie_id = 2 });
//Add Tickets to the list
List<tickets> ticketsItems = new List<tickets>();
ticketsItems.Add(new tickets() { id = 1, schedule_id = 1 });
ticketsItems.Add(new tickets() { id = 2, schedule_id = 1 });
ticketsItems.Add(new tickets() { id = 3, schedule_id = 2 });
ticketsItems.Add(new tickets() { id = 4, schedule_id = 2 });
ticketsItems.Add(new tickets() { id = 5, schedule_id = 2 });
ticketsItems.Add(new tickets() { id = 6, schedule_id = 3 });
ticketsItems.Add(new tickets() { id = 7, schedule_id = 3 });
ticketsItems.Add(new tickets() { id = 8, schedule_id = 3 });
ticketsItems.Add(new tickets() { id = 9, schedule_id = 3 });
ticketsItems.Add(new tickets() { id = 10, schedule_id = 4 });
var query = from final in (from m in moviesItems
join sch in schedulesItems on m.id equals sch.movie_id
join tk in ticketsItems on sch.id equals tk.schedule_id
select new { movieID = m.id, movieName = m.name, schID = sch.id, tkID = tk.id })
group final by new { final.movieID, final.movieName, final.schID } into g
orderby g.Count() descending
select new { g.Key.movieID, g.Key.movieName, g.Key.schID, tiketSold = g.Count() };
}

This query is closest to your SQL but probably you need LEFT JOIN. Also it can be simplified using navigation properties if you provide model.
var hotMovie =
from m in _db.movies
join sch in _db.schedules on m.id equals sch.movie_id
join tk in _db.tickets on sch.id equals tk.schedule_id
group tk by new { movieID = m.id, movieName = m.name, scheduleId = sch.id } into g
orderby g.Sum(x => x.id != null ? 1 : 0) descending
select new
{
g.Key.movieID,
g.Key.movieName,
g.Key.scheduleId,
tiketSold = g.Sum(x => x.id != null ? 1 : 0)
};

Related

Split a single list to 'x' numbers of lists during runtime? [duplicate]

I have an object:
public class Customer
{
public int ID { get; set; }
public string Name { get; set; }
public int GroupID { get; set; }
}
I return a list that may look like the following:
List<Customer> CustomerList = new List<Customer>();
CustomerList.Add( new Customer { ID = 1, Name = "One", GroupID = 1 } );
CustomerList.Add( new Customer { ID = 2, Name = "Two", GroupID = 1 } );
CustomerList.Add( new Customer { ID = 3, Name = "Three", GroupID = 2 } );
CustomerList.Add( new Customer { ID = 4, Name = "Four", GroupID = 1 } );
CustomerList.Add( new Customer { ID = 5, Name = "Five", GroupID = 3 } );
CustomerList.Add( new Customer { ID = 6, Name = "Six", GroupID = 3 } );
I want to return a linq query which will look like
CustomerList
GroupID =1
UserID = 1, UserName = "UserOne", GroupID = 1
UserID = 2, UserName = "UserTwo", GroupID = 1
UserID = 4, UserName = "UserFour", GroupID = 1
GroupID =2
UserID = 3, UserName = "UserThree", GroupID = 2
GroupID =3
UserID = 5, UserName = "UserFive", GroupID = 3
UserID = 6, UserName = "UserSix",
I tried from
Using Linq to group a list of objects into a new grouped list of list of objects
code
var groupedCustomerList = CustomerList
.GroupBy(u => u.GroupID)
.Select(grp => grp.ToList())
.ToList();
works but does not give the desired output.
var groupedCustomerList = CustomerList.GroupBy(u => u.GroupID)
.Select(grp =>new { GroupID =grp.Key, CustomerList = grp.ToList()})
.ToList();
var groupedCustomerList = CustomerList
.GroupBy(u => u.GroupID, u=>{
u.Name = "User" + u.Name;
return u;
}, (key,g)=>g.ToList())
.ToList();
If you don't want to change the original data, you should add some method (kind of clone and modify) to your class like this:
public class Customer {
public int ID { get; set; }
public string Name { get; set; }
public int GroupID { get; set; }
public Customer CloneWithNamePrepend(string prepend){
return new Customer(){
ID = this.ID,
Name = prepend + this.Name,
GroupID = this.GroupID
};
}
}
//Then
var groupedCustomerList = CustomerList
.GroupBy(u => u.GroupID, u=>u.CloneWithNamePrepend("User"), (key,g)=>g.ToList())
.ToList();
I think you may want to display the Customer differently without modifying the original data. If so you should design your class Customer differently, like this:
public class Customer {
public int ID { get; set; }
public string Name { get; set; }
public int GroupID { get; set; }
public string Prefix {get;set;}
public string FullName {
get { return Prefix + Name;}
}
}
//then to display the fullname, just get the customer.FullName;
//You can also try adding some override of ToString() to your class
var groupedCustomerList = CustomerList
.GroupBy(u => {u.Prefix="User", return u.GroupID;} , (key,g)=>g.ToList())
.ToList();
is this what you want?
var grouped = CustomerList.GroupBy(m => m.GroupID).Select((n) => new { GroupId = n.Key, Items = n.ToList() });
var result = from cx in CustomerList
group cx by cx.GroupID into cxGroup
orderby cxGroup.Key
select cxGroup;
foreach (var cxGroup in result) {
Console.WriteLine(String.Format("GroupID = {0}", cxGroup.Key));
foreach (var cx in cxGroup) {
Console.WriteLine(String.Format("\tUserID = {0}, UserName = {1}, GroupID = {2}",
new object[] { cx.ID, cx.Name, cx.GroupID }));
}
}
The desired result can be obtained using IGrouping, which represents a collection of objects that have a common key in this case a GroupID
var newCustomerList = CustomerList.GroupBy(u => u.GroupID)
.Select(group => new { GroupID = group.Key, Customers = group.ToList() })
.ToList();

LINQ get a record with max date from multiple joins

I have three tables: Courses, CourseLocations, CourseSchedules
Each Course can be held in one or more Locations (1-to-many)
Each Location can host one or more Schedules (1-to-many)
I need to get all the courses, unique names, that have a Schedules.Date> Today and show also the MAX value of the date contained in the table CourseSchedules
My current linq code is:
var courses = (from c in db.Courses
join cl in db.CourseLocations on c.CourseID equals cl.CourseID
join cs in db.CourseSchedules on cl.CourseLocationID equals cs.CourseLocationID
where c.CourseStatusID == 1 && c.DeleteDate == null && ((c.CourseCategoryID == 1 && cs.EndDate >= courseEndDateFilter) || (c.CourseCategoryID == 3))
select new
{
c.CourseID,
CourseName = c.Name,
CourseEndDate = cs.EndDate
}).Distinct().OrderBy(o => o.CourseCategoryID).ThenBy(o => o.CourseName);
Where courseEndDateFilter is a variable used to define the date to filter.
The problem with the above query is that I get all the courses duplicated and not only the one with the MAX value of cs.EndDate
Is there a way (efficient) to do it?
#Ehsan is correct. You need a group by and then get the max value of EndDate. Given the following models:
public class Course
{
public int CourseID { get; set; }
public string Name { get; set; }
public int CourseStatusID { get; set; }
public int CourseCategoryID { get; set; }
public DateTime? DeleteDate { get; set; }
}
public class CourseLocation
{
public int CourseLocationID { get; set; }
public int CourseID { get; set; }
}
public class CourseSchedules
{
public int CourseLocationID { get; set; }
public DateTime EndDate { get; set; }
}
I created the following in memory objects:
var courses = new List<Course>
{
new Course { CourseID = 1, Name = "Test1", CourseCategoryID = 1, CourseStatusID = 1, DeleteDate = null },
new Course { CourseID = 2, Name = "Test2", CourseCategoryID = 1, CourseStatusID = 1, DeleteDate = null },
new Course { CourseID = 3, Name = "Test3", CourseCategoryID = 3, CourseStatusID = 1, DeleteDate = null }
};
var courseLocations = new List<CourseLocation>
{
new CourseLocation{ CourseID = 1, CourseLocationID = 1 },
new CourseLocation{ CourseID = 2, CourseLocationID = 1 },
new CourseLocation{ CourseID = 3, CourseLocationID = 1 },
new CourseLocation{ CourseID = 1, CourseLocationID = 2 },
new CourseLocation{ CourseID = 2, CourseLocationID = 2 },
new CourseLocation{ CourseID = 3, CourseLocationID = 2 }
};
var courseSchedules = new List<CourseSchedules>
{
new CourseSchedules { CourseLocationID = 1, EndDate = DateTime.Now.AddDays(10) },
new CourseSchedules { CourseLocationID = 1, EndDate = DateTime.Now.AddYears(1) }
};
Then the query would be the following to get Max EndDate:
var result = (from c in courses
join cl in courseLocations on c.CourseID equals cl.CourseID
join cs in courseSchedules on cl.CourseLocationID equals cs.CourseLocationID
where c.CourseStatusID == 1 && c.DeleteDate == null &&
(c.CourseCategoryID == 1 && cs.EndDate >= DateTime.Now || c.CourseCategoryID == 3)
select new
{
c.CourseID,
CourseName = c.Name,
CourseEndDate = cs.EndDate,
c.CourseCategoryID
})
.GroupBy(arg => new
{
arg.CourseID,
arg.CourseName,
arg.CourseCategoryID
})
.Select(grouping => new
{
grouping.Key.CourseID,
grouping.Key.CourseName,
CourseEndDate = grouping.Max(arg => arg.CourseEndDate),
grouping.Key.CourseCategoryID
})
.OrderBy(o => o.CourseCategoryID)
.ThenBy(o => o.CourseName);
I'm not sure this will work since it's not like I can actually compile it.
The problem I see right away is that you're filter by a few things at the base, some of which don't include the locations but you want the date from the locations anyway...
var courses = (from c in db.Courses
join cl in db.CourseLocations on c.CourseID equals cl.CourseID
join cs in db.CourseSchedules on cl.CourseLocationID equals cs.CourseLocationID
where c.CourseStatusID == 1 && c.DeleteDate == null && (c.CourseCategoryID == 3 ||
db.CourseLocations.Any(cl => cl.CourseID equals c.CourseID &&
db.CourseSchedules.Any(cs => cs.CourseLocationID equals cl.CourseLocationID &&
((c.CourseCategoryID == 1 && cs.EndDate >= courseEndDateFilter))
)
))
select new
{
c.CourseID,
CourseName = c.Name,
CourseEndDate = db.CourseSchedules.Where(cs => db.CourseLocations.Any(cl => cl.CourseID equals c.CourseID && cs.CourseLocationID equals cl.CourseLocationID)).Max(cs => cs.EndDate),
c.CourseCategoryID
});

Entity Framework Linq, Left Join and group with SUM and Count

I need a little help in converting SQL to Linq. It's pretty straight forward in MySQL...
Table: customers
ID Name
1 Bill
2 John
Table: purchases
ID CustomerID CompletedTransaction
1 1 False
2 2 True
3 1 True
4 1 True
SELECT c.ID
c.Name,
COUNT(p.ID) AS TotalPurchases,
SUM(CASE WHEN p.CompletedTransaction = TRUE THEN 1 ELSE 0 END) AS TotalCompleted
FROM customers c
LEFT JOIN purchases p ON c.ID = p.CustomerID
GROUP BY c.ID
Expected Result:
1, Bill, 3, 2
2, John, 1, 1
I've seen a few examples on how to implement a left join in Linq but I'm not sure how to include a SUM and Count into this. I've seen examples in Linq where the fields returned are selected from the group keys. Does this mean that if I have more fields in the customers table such as address and other contact details which I'd like to return, I'd have to include them in the join to then be able to select them? Hope this makes sense. Appreciate any help or links that might point me in the right direction.
Thanks
var answer = (from c in db.customers
join p in db.purchases
on c.ID = p.CustomerID into subs
from sub in subs.DefaultIfEmpty()
group sub by new { c.ID, c.Name } into gr
select new {
gr.Key.ID,
gr.Key.Name,
Total = gr.Count(x => x != null),
CountCompleted = gr.Count(x => x != null && x.CompletedTransaction)
}).ToList();
Here's the sample
class Program
{
static void Main(string[] args)
{
List<Customers> customers = new List<Customers>();
customers.Add(new Customers() { ID = 1, Name = "Bill" });
customers.Add(new Customers() { ID = 2, Name = "John" });
List<Purchases> purchases = new List<Purchases>();
purchases.Add(new Purchases() { ID = 1, CustomerID = 1, CompletedTransaction = false });
purchases.Add(new Purchases() { ID = 2, CustomerID = 2, CompletedTransaction = true });
purchases.Add(new Purchases() { ID = 3, CustomerID = 1, CompletedTransaction = true });
purchases.Add(new Purchases() { ID = 4, CustomerID = 1, CompletedTransaction = true });
IEnumerable<JoinResult> results = from c in customers
join p in purchases
on c.ID equals p.CustomerID
group new { c, p } by new {p.CustomerID, c.Name} into r
select new JoinResult
{
CustomerID = r.Key.CustomerID,
CustomerName = r.Key.Name,
TotalPurchases = r.Count(),
TotalCompleteTransaction = r.Where(s=> s.p.CompletedTransaction).Count()
};
foreach(JoinResult r in results)
{
Console.WriteLine($"CustomerID : {r.CustomerID} | Name : {r.CustomerName} | TotalPurchases : {r.TotalPurchases} | TotalCompleteTransaction : {r.TotalCompleteTransaction}");
}
Console.ReadKey();
}
}
class Customers
{
public int ID { get; set; }
public string Name { get; set; }
}
class Purchases
{
public int ID { get; set; }
public int CustomerID { get; set; }
public bool CompletedTransaction { get; set; }
}
class JoinResult
{
public int CustomerID { get; set; }
public string CustomerName { get; set; }
public int TotalPurchases { get; set; }
public int TotalCompleteTransaction { get; set; }
}
Result

Query c# List to limit children but return parents

I have a nested list structure with Customers -> Orders -> OrderItems. I am trying to find a LINQ or other query that will return the Customers and their nested items where the OrderItem quantity = 1. However, it should not return any Orders or OrderItems where the quantity != 1.
I have tried this:
var customers2 = customers.Where(c => c.Orders.Any(o => o.OrderItems.Exists(oi => oi.Quantity == 1)));
It correctly returns only Customers with order items quantity = 1, but it also returns all other Orders and Order Items as well.
I can get the desired results with a couple of For-each loops, but I would like to find something more elegant:
foreach (var customer in customers2)
{
customer.Orders = customer.Orders.Where(o => o.OrderItems.Exists(oi => oi.Quantity == 1)).ToList();
foreach (var order in customer.Orders)
{
order.OrderItems = order.OrderItems.Where(oi => oi.Quantity == 1).ToList();
}
}
Here is the object structure and some sample data.
public class Customer
{
public int CustomerId { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public List<Order> Orders { get; set; }
}
public class Order
{
public int OrderId { get; set; }
public int CustomerId { get; set; }
public DateTime OrderDate { get; set; }
public bool Shipped { get; set; }
public List<OrderItem> OrderItems { get; set; }
}
public class OrderItem
{
public int OrderItemId { get; set; }
public int OrderId { get; set; }
public string ItemName { get; set; }
public int Quantity { get; set; }
}
var customers = new List<Customer>
{
new Customer
{
CustomerId = 1,
Name = "Shawn",
Address = "123 Main Street",
Orders = new List<Order>()
{
new Order()
{
OrderId = 100,
CustomerId = 1,
OrderDate = DateTime.Now,
Shipped = true,
OrderItems = new List<OrderItem>()
{
new OrderItem()
{
OrderItemId = 200,
OrderId = 100,
ItemName = "Computer",
Quantity = 1
},
new OrderItem()
{
OrderItemId = 206,
OrderId = 100,
ItemName = "Hard Drive",
Quantity = 2
}
}
},
new Order()
{
OrderId = 106,
CustomerId = 1,
OrderDate = DateTime.Now,
Shipped = true,
OrderItems = new List<OrderItem>()
{
new OrderItem()
{
OrderItemId = 207,
OrderId = 106,
ItemName = "Monitor",
Quantity = 3
},
new OrderItem()
{
OrderItemId = 208,
OrderId = 106,
ItemName = "DVD Burner",
Quantity = 2
}
}
}
}
},
new Customer
{
CustomerId = 2,
Name = "Arianna",
Address = "456 Main Street",
Orders = new List<Order>()
{
new Order()
{
OrderId = 101,
CustomerId = 2,
OrderDate = DateTime.Now.AddDays(-10),
Shipped = true,
OrderItems = new List<OrderItem>()
{
new OrderItem()
{
OrderItemId = 201,
OrderId = 101,
ItemName = "barbie",
Quantity = 2
}
}
}
}
},
new Customer
{
CustomerId = 3,
Name = "Ryan",
Address = "789 Main Street",
Orders = new List<Order>()
{
new Order()
{
OrderId = 102,
CustomerId = 3,
OrderDate = DateTime.Now.AddDays(-5),
Shipped = true,
OrderItems = new List<OrderItem>()
{
new OrderItem()
{
OrderItemId = 203,
OrderId = 103,
ItemName = "Minecraft",
Quantity = 2
}
}
}
}
}
};
You're on the right path with
var customers2 = customers
.Where(c => c.Orders.Any(o => o.OrderItems.Exists(oi => oi.Quantity == 1)));
You just need an additional step as you can't filter the orders and the customers at the same time, you already filtered the customers to get only those you're interested in, now filter the orders themselves
var customers2 = customers
.Where(c => c.Orders.Any(o => o.OrderItems.Exists(oi => oi.Quantity == 1)))
.Select(c => c.Orders.Where(o => o.OrderItems(o => o.OrderItems.Exists(oi => oi.Quantity == 1)));
This however leaves you with an ienumerable of ienumerable of orders, and not the customers, but you can't do exactly what you want (retrieve the customers and have their order property changed) as that would change their original order list, what you can do is create an Anonymous type to store both the orders and Customer in your query in the select as such:
var customers2 = customers
.Where(c => c.Orders.Any(o => o.OrderItems.Exists(oi => oi.Quantity == 1)))
.Select(c => new
{
Customer = c,
FilteredOrders = c.Orders.Where(o => o.OrderItems(o => o.OrderItems.Exists(oi => oi.Quantity == 1))
});
Now you can use this as such
foreach(var cust in customers2)
{
cust.Customer // your original Customer object
cust.Customer.Orders // your original orders collection for this Customer
cust.FilteredOrders // only the orders you're interested in for this customer
}
I imagine there's a shorter solution but this works:
var goodCusts = new List<Customer>();
foreach(var customer in customers)
{
var testCust = customer;
for (int i = testCust.Orders.Count - 1; i >= 0; i--)
{
if (testCust.Orders[i].OrderItems.Count != 1)
testCust.Orders.RemoveAt(i);
}
if (testCust.Orders.Any())
goodCusts.Add(testCust);
}
It does create a new collection, though. It just runs through each customer, removes any Orders with OrderItems.Count != 1, then tests if that customer has any Orders left. If it does, it gets added to the List<Customer> results.
Thanks to #StripplingWarrior I think I have arrived at the answer, though prob still not the most elegant:
var customers2 = customers.Where(x => x.Orders != null && x.Orders.Any(y => y.OrderItems != null && y.OrderItems.Any(z => z.Quantity == 1)));
customers2.ToList().ForEach(x =>
{
x.Orders.ForEach(y =>
{
y.OrderItems.RemoveAll(z => z == null || z.Quantity != 1);
});
x.Orders.RemoveAll(y => y == null || y.OrderItems.Count == 0);
});
return customers2;
This will get all customers with the specific orders where the order items quantity is the desired amount.
To use this it will remove all orderitems that do not have one item quantity. So you need to clone the list before using this function.
public static List<Customer> GetCustomersWithOrderItemQuantity(List<Customer> customers, int quantity)
{
var customers2 = customers.TakeWhile(c => c.Orders.Any(o => o.OrderItems.Any(oi => oi.Quantity == quantity))).ToList();
customers2.ForEach(cust => cust.Orders.ForEach(o => o.OrderItems.RemoveAll(oi => oi.Quantity != quantity)));
return customers2;
}
You can use like this to input a specific quantity.
var customers2 = GetCustomersWithOrderItemQuantity(customers, 1);
If you want all orders where at least one item has quantity of 1 then use this.
public static IEnumerable<Customer> GetCustomersWithOrderItemQuantity(List<Customer> customers, int quantity)
{
return customers.TakeWhile(c => c.Orders.Any(o => o.OrderItems.Any(oi => oi.Quantity == quantity)));
}
The above can be used the same as the other one but will show all orders with at least one order item quantity of 1 in your example above.

Using LINQ to group a list of objects

I have an object:
public class Customer
{
public int ID { get; set; }
public string Name { get; set; }
public int GroupID { get; set; }
}
I return a list that may look like the following:
List<Customer> CustomerList = new List<Customer>();
CustomerList.Add( new Customer { ID = 1, Name = "One", GroupID = 1 } );
CustomerList.Add( new Customer { ID = 2, Name = "Two", GroupID = 1 } );
CustomerList.Add( new Customer { ID = 3, Name = "Three", GroupID = 2 } );
CustomerList.Add( new Customer { ID = 4, Name = "Four", GroupID = 1 } );
CustomerList.Add( new Customer { ID = 5, Name = "Five", GroupID = 3 } );
CustomerList.Add( new Customer { ID = 6, Name = "Six", GroupID = 3 } );
I want to return a linq query which will look like
CustomerList
GroupID =1
UserID = 1, UserName = "UserOne", GroupID = 1
UserID = 2, UserName = "UserTwo", GroupID = 1
UserID = 4, UserName = "UserFour", GroupID = 1
GroupID =2
UserID = 3, UserName = "UserThree", GroupID = 2
GroupID =3
UserID = 5, UserName = "UserFive", GroupID = 3
UserID = 6, UserName = "UserSix",
I tried from
Using Linq to group a list of objects into a new grouped list of list of objects
code
var groupedCustomerList = CustomerList
.GroupBy(u => u.GroupID)
.Select(grp => grp.ToList())
.ToList();
works but does not give the desired output.
var groupedCustomerList = CustomerList.GroupBy(u => u.GroupID)
.Select(grp =>new { GroupID =grp.Key, CustomerList = grp.ToList()})
.ToList();
var groupedCustomerList = CustomerList
.GroupBy(u => u.GroupID, u=>{
u.Name = "User" + u.Name;
return u;
}, (key,g)=>g.ToList())
.ToList();
If you don't want to change the original data, you should add some method (kind of clone and modify) to your class like this:
public class Customer {
public int ID { get; set; }
public string Name { get; set; }
public int GroupID { get; set; }
public Customer CloneWithNamePrepend(string prepend){
return new Customer(){
ID = this.ID,
Name = prepend + this.Name,
GroupID = this.GroupID
};
}
}
//Then
var groupedCustomerList = CustomerList
.GroupBy(u => u.GroupID, u=>u.CloneWithNamePrepend("User"), (key,g)=>g.ToList())
.ToList();
I think you may want to display the Customer differently without modifying the original data. If so you should design your class Customer differently, like this:
public class Customer {
public int ID { get; set; }
public string Name { get; set; }
public int GroupID { get; set; }
public string Prefix {get;set;}
public string FullName {
get { return Prefix + Name;}
}
}
//then to display the fullname, just get the customer.FullName;
//You can also try adding some override of ToString() to your class
var groupedCustomerList = CustomerList
.GroupBy(u => {u.Prefix="User", return u.GroupID;} , (key,g)=>g.ToList())
.ToList();
is this what you want?
var grouped = CustomerList.GroupBy(m => m.GroupID).Select((n) => new { GroupId = n.Key, Items = n.ToList() });
var result = from cx in CustomerList
group cx by cx.GroupID into cxGroup
orderby cxGroup.Key
select cxGroup;
foreach (var cxGroup in result) {
Console.WriteLine(String.Format("GroupID = {0}", cxGroup.Key));
foreach (var cx in cxGroup) {
Console.WriteLine(String.Format("\tUserID = {0}, UserName = {1}, GroupID = {2}",
new object[] { cx.ID, cx.Name, cx.GroupID }));
}
}
The desired result can be obtained using IGrouping, which represents a collection of objects that have a common key in this case a GroupID
var newCustomerList = CustomerList.GroupBy(u => u.GroupID)
.Select(group => new { GroupID = group.Key, Customers = group.ToList() })
.ToList();

Categories

Resources