I have a query
SELECT * FROM member
ORDER BY d_no.member DESC, DateBirth ASC
I am thinking how can I do this in Linq?
I have a List<member>
I used this
Var Result = member.OrderByDescending(s => s.d_no).OrderBy(y => y.DateBirth ).ToList();
Is not working, any Idea?
OrderByDescending returns an instance of type IOrderedEnumerable<TSource>.
You can then call ThenBy or ThenByDescending to apply a second (or third) ordering constraint.
var Result = member.OrderByDescending(s => s.d_no)
.ThenBy(y => y.DateBirth )
.ToList();
Var Result = member.OrderByDescending(s => s.d_no,).ThenBy(y => y.DateBirth ).ToList();
Is there any reason to use method instead of query?
var result = (from m in member
order by m.d_no descending, m.DateBirth ascending
select m).ToList();
Related
Is there any way to perform an OrderBy with an aggregated field (string.Join)?
var query = <Some IQueryable<T>>;
query = query.OrderBy(x => string.Join(",", x.Values.Select(v => v.Name)));
I am building dynamic queries and came up a need to order by a column that is agreggated like the above example.
Thanks in advance
You need to first project the aggregated column before you can do OrderBy.
query = query.Select(x=>new {
Item = x,
Agg = x => string.Join(",", x.Values.Select(v => v.Name))
}).OrderBy(a=>a.Agg).Select(a=>a.Item)
Suppose we have the typical Customers and Orders relationship, where a Customer can have several Orders, and the Orders contain the CustomerId as FK.
I think this code returns the whole Order entity for the latest order:
Order latestOrder = (from o in context.Orders
//where conditions or joins to be included here
group o by o.CustomerId into grp
select grp.OrderByDescending(g => g.OrderDate).First())
How can I return only the OrderNumber, of type string, instead of the whole entity? (or empty if it has none)
string latestOrderNumber = (?)
thanks.
You need to call Select(g => g.OrderNumber) before First() And you need to call FirstOrDefault again in order to retrieve a single OrderNumber rather than a IQueryable<string>
string latestOrderNumber = (from o in context.Orders
group o by o.CustomerId into grp
select grp.OrderByDescending(g => g.OrderDate)
.Select(g => g.OrderNumber)
.FirstOrDefault()
).FirstOrDefault();
You could try something like this:
Order latestOrder = (from o in context.Orders
//where conditions or joins to be included here
group o by o.CustomerId into grp
select grp.OrderByDescending(g => g.OrderDate).FirstOrDefault());
It's a good practice to use the FirstOrDefault. If not any order found, then the result is null. Then you check if the result is not null and you just read the property of the returned item.
if(latestOrder!=null)
lastOrdeNumber = lastOrder.OrderNumber;
Try this one. Hope it can help you!
var result = context.Orders.OrderByDescending(o => o.OrderDate)
.GroupBy(x => x.CustomerId)
.Select(grp => grp.First().OrderNumber);
The main objective is to return a list of ingredients in a sorted order according to popularity (which is indicated by how many people have as their favorite a particular ingredient). The SQL equivalent is below:
select distinct COUNT(PersonalInfoes.FavoriteIngredient_ID) as NoUsing,
Ingredients.Name
from PersonalInfoes right join Ingredients
on PersonalInfoes.FavoriteIngredient_ID = Ingredients.ID
group by Ingredients.Name
order by NoUsing desc
What is the equivalent SQL query of method syntax that will produce the same result as above?
The closest I've got is this:
from i in db.Ingredients
join p in db.PersonalInfos on i.ID equals p.FavoriteIngredient.ID into ing
from p in ing.DefaultIfEmpty()
group i by i.Name into g
from p in g
orderby g.Count() descending
select new { Name = g.Key, Count = g.Count() }.Name;
Your query does a left outer join to include ingredients with no favorites. The problem is, for each ingredient with no favorites, you are counting the single value that gets produced by DefaultIfEmpty(). You can exclude the default values when counting like this:
orderby g.Count(x => x != null) descending
You actually don't have to perform a left join. You can just sum the counts of the groups from your group join:
from i in db.Ingredients
join p in db.PersonalInfos on i.ID equals p.FavoriteIngredient.ID into faves
group faves.Count() by i.Name into faveCounts
let count = faveCounts.Sum()
orderby count descending
select new { Name = faveCounts.Key, Count = count };
A subjective problem with your code is it's very confusing with all of the group by and from clauses. If you find this to be an issue, you can try using more descriptive names, using subqueries, or using method syntax.
Edit: Here is a method syntax version. It is not a direct conversion from the query syntax version because that would be quite ugly.
db.Ingredients
.GroupJoin(db.PersonalInfos,
i => i.ID,
p => p.ID,
(i, g) => new { i.Name, FaveCount = g.Count() })
.GroupBy(x => x.Name,
(key, grp) => new { Name = key, Count = grp.Sum(y => y.FaveCount) })
.OrderByDescending(x => x.Count);
Say I have a method definition as such:
public CustomerOrderData[] GetCustomerOrderData(string[] CustomerIDs)
{
var query = (from a in db.Customer
join b in db.Order on a.CustomerID equals v.CustomerID
orderby CustomerIDs
select new CustomerOrderData()
{
//populate props here
}).ToArray();
}
My CustomerIDs in input param could be {"1","3","400","200"}
I want my return array to be ordered in the above fashion. Is there an easy way to achive this?
My solution was to put it into a Dictionary and then create a new array while looping through my CustomerIDs collection.
CustomerOrderData does have a property named CustomerID
If you materialize the query, you should be able to find the index of the id in your array and use it as the ordering parameter. Shown below using extension methods.
var ordering = CustomerIDs.ToList();
var query = db.Customer.Join( db.Order, (a,b) => a.CustomerID == b.CustomerID )
.AsEnumerable()
.OrderBy( j => ordering.IndexOf( j.Customer.CustomerID ) )
.Select( j => new CustomerOrderData {
// do selection
})
.ToArray();
I think this solves problem:
var orderedArray = YourCustomArray.OrderBy(s => s).ToArray();
if the customerIds always will be numbers then cast it and order it before using it into ur query
var orderedIds = CustomerIDs.Cast<int>().OrderBy(x => x);
You could use IndexOf:
orderby ContactIds.IndexOf(a.CustomerId)
Note that this might not be efficient for large sets.
You could create a structure to lookup the desired index using the customerid.
string[] CustomerIDs;
Dictionary<string, int> customerIDOrdering = CustomerIds
.Select((c, i) => new (id = c.CustomerID, i = i})
.ToDictionary(x => x.id, x => x.i);
var query = from c in ...
orderby customerIDOrdering[c.CustomerID]
...
The join clause preserves the order of the outer sequence:
"The Join operator preserves the order of the outer sequence elements, and for each outer element, the order of the matching inner sequence elements."
http://msdn.microsoft.com/en-us/library/bb394939.aspx
So you should not need to orderby at all:
from orderIndex in CustomerIDs
join a in db.Customer on orderIndex equals a.CustomerID
join b in db.Order on a.CustomerID equals v.CustomerID
Consider a SQL Server table that's used to store events for auditing.
The need is to get only that latest entry for each CustID. We want to get the entire object/row. I am assuming that a GroupBy() will be needed in the query. Here's the query so far:
var custsLastAccess = db.CustAccesses
.Where(c.AccessReason.Length>0)
.GroupBy(c => c.CustID)
// .Select()
.ToList();
// (?) where to put the c.Max(cu=>cu.AccessDate)
Question:
How can I create the query to select the latest(the maximum AccessDate) record/object for each CustID?
I'm wondering if something like:
var custsLastAccess = db.CustAccesses
.Where(c.AccessReason.Length>0)
.GroupBy(c => c.CustID)
.Select(grp => new {
grp.Key,
LastAccess = grp
.OrderByDescending(x => x.AccessDate)
.Select(x => x.AccessDate)
.FirstOrDefault()
}).ToList();
you could also try OrderBy() and Last()
Using LINQ syntax, which I think looks cleaner:
var custsLastAccess = from c in db.CustAccesses
group c by c.CustID into grp
select grp.OrderByDescending(c => c.AccessDate).FirstOrDefault();
Here: this uses max rather than OrderByDesc, so should be more efficient.
var subquery = from c in CustAccesses
group c by c.CustID into g
select new
{
CustID = g.Key,
AccessDate = g.Max(a => a.AccessDate)
};
var query = from c in CustAccesses
join s in subquery
on c.CustID equals s.CustID
where c.AccessDate == s.AccessDate
&& !string.IsNullOrEmpty(c.AccessReason)
select c;