Reputation: 712
I have the objects as below:
public class CustomerSequence
{
public string CustomerName { get; set; }
public int Sequence { get; set; }
}
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
public string Component { get; set; }
}
Let's say I have 2 Lists Object
Customer: CustomerSequence:
Id Name Component CustomerName Sequence
1 AAA AAAAAA AAA 2
2 BBB BBBBBBB BBB 4
3 CCC CCCCC CCC 1
DDD 3
As you can see there is no DDD in List.
I want to sort the List Customer based on the List CustomerSequence
Result is:
Customer:
Id Name Component
3 CCC CCCCC
1 AAA AAAAAA
2 BBB BBBBBBB
Anyone can help me please.
Upvotes: 1
Views: 76
Reputation: 10694
Use Join
var customers = from cust in Customer
join cust_seq in CustomerSequence
on cust.Name equals cust_seq.CustomerName
orderby cust_seq.Sequence
select cust;
Upvotes: 1
Reputation: 236268
Join both sequences on customer name, then order by sequence value:
from c in customers
join cs in customerSequences
on c.Name equals cs.CustomerName
orderby cs.Sequence
select c;
Lambda syntax is not that beautiful, and it will look like
customers.Join(customerSequences,
c => c.Name, cs => cs.CustomerName, (c,cs) => new { c, cs })
.OrderBy(x => x.cs.Sequence)
.Select(x => x.c)
Internally join uses lookup for second sequence, which is much more effective then linear search with Where
.
If it is possible that there is no CustomerSequencs matching customer, or there is more than one match, then use group join:
from c in customers
join cs in customerSequences
on c.Name equals cs.CustomerName into g
orderby g.Select(cs => cs.Sequence).FirstOrDefault()
select c
This query uses 0 form missing sequences, and first matched value if there is more than one sequence for customer.
Upvotes: 3
Reputation: 18474
Try this
Customer.OrderBy(x => CustomerSequence.Where(y => y.CustomerName == x.Name)
.Select(y => y.Sequence)
.FirstOrDefault())
Alternatively you can use a join which would be better if the source was a database
var sorted =
from c in customer
join csj in customerSequence on c.Name equals csj.CustomerName into customerSequenceJoined
from cs in customerSequenceJoined.DefaultIfEmpty()
orderby cs == null ? 0 : cs.Sequence
select c;
The cs == null ? 0 : cs.Sequence
deals with the case when there is no matching record in the sequence collection. You could use int.MaxValue
if you want these items to appear last.
Upvotes: 2
Reputation: 117134
I tend to use a dictionary for this sort of thing.
var customerSequence =
customerSequences
.ToDictionary(x => x.CustomerName, x => x.Sequence);
var sortedCustomers =
customers
.OrderBy(x => customerSequence[x.Name])
.ToList();
Upvotes: 0