linq multiple order DESCENDING - linq

.OrderBy(y => y.Year).ThenBy(m => m.Month);
How to set descending order?
EDIT:
I tried this:
var result = (from dn in db.DealNotes
where dn.DealID == dealID
group dn by new { month = dn.Date.Month, year = dn.Date.Year } into date
orderby date.Key.year descending
orderby date.Key.month descending
select new DealNoteDateListView {
DisplayDate = date.Key.month + "-" + date.Key.year,
Month = date.Key.month,
Year = date.Key.year,
Count = date.Count()
})
//.OrderBy(y => y.Year).ThenBy(m => m.Month)
;
And it seems working. Is it wrong to use orderby twice like I used it here?

You can get the descending ordering by using a different pair of methods:
items.OrderByDescending(y => y.Year).ThenByDescending(m => m.Month);
Using LINQ query, you can write:
from date in db.Dates
orderby date.Key.year descending, date.Key.month descending
select new { ... }
The trick is that you need only one orderby clause - if you add multiple of these, the list will be re-sorted each time. To sort elements that have the first key equal using another key, you need to separate them using , (orderby is translated to OrderBy or OrderByDescending while , is translated to ThenBy or ThenByDescending).

Related

Linq orderby and distinct

I have a table set up as follows:
Section SectionOrder
Sect1 1
Sect2 2
Sect3 3
Sect3 3
Sect1 1
Sect2 2
I need to pull out distinct sections in correct section order. Here is the linq that I'm using, but it's not putting them in the correct order for some reason.
var myVar = (from x in context.Documents
orderby x.SectionOrder ascending
select x.Section).Distinct();
I then want to be able to loop through myVar and put each item in a list as follows:
foreach (var t in myVar)
{
listOfDocTypeSections.Add(t);
}
The ordering of OrderBy and Distinct matters: while OrderBy produced an ordered sequence, Distinct doesn't. You need to put Distinct first, and then use OrderBy. However, since you take Distinct on one attribute, and order on the other attribute, you need to do it differently:
var myVar = context
.Documents
.GroupBy(x => x => x.Section) // This replaces Distinct()
.OrderBy(g => g.FirstOrDefault().SectionOrder) // There will be no default
.Select(g => g.Key);
This approach replaces Distinct with GroupBy, and orders on the first SectionOrder item of a group. You can change this sorting strategy to sort on some other item within the Section, say, Min or Max value of SectionOrder:
var myVar = context
.Documents
.GroupBy(x => x => x.Section)
.OrderBy(g => g.Max(x => x.SectionOrder))
.Select(g => g.Key);

How to find Distinct in more than one column in LINQ

I have a LINQ statement that returns many columns. I need to find distinct of unique combination of two columns. What is the best way to do this.
var productAttributeQuery =
from pa in ctx.exch_productattributeSet
join pp in ctx.exch_parentproductSet
on pa.exch_ParentProductId.Id equals pp.Id
join ep in ctx.exch_exchangeproductSet
on pp.exch_parentproductId equals ep.exch_ParentProductId.Id
where pa.exch_EffBeginDate <= effectiveDateForBeginCompare
&& pa.exch_EffEndDate >= effectiveDateForEndCompare
&& pa.statuscode == StusCodeEnum.Active
where pp.exch_EffBeginDate <= effectiveDateForBeginCompare
&& pp.exch_EffEndDate >= effectiveDateForEndCompare
&& pp.statuscode == StatusCodeEnum.Active
where ep.statuscode == StatusCodeEnum.Active
select new ProductAttributeDto
{
ParentProductId = pa.exch_ParentProductId.Id,
AttributeId = pa.exch_AttributeId.Id,
AttributeValue = pa.exch_Value,
AttributeRawValue = pa.exch_RawValue
};
return productAttributeQuery.ToList();
I want to get Distinct combination of ParentProductId and AttributeId from this list
You can group by anonymous type and select keys (they will be distinct)
var query = from p in productAttributeQuery
group p by new {
p.ParentProductId,
p.AttributeId
} into g
select g.Key;
You can use same approach with you original query if you want to get distinct pairs on server side.
Another approach - project results into pairs and get distinct from them:
var query = productAttributeQuery
.Select(p => new { p.ParentProductId, p.AttributeId })
.Distinct();

Linq expression for left join and filter for the inner table

I want to know how to make Linq expression that has the same effect as these SQL query
SELECT item.*, priceforitem.*
FROM
item
LEFT JOIN priceforitem
ON priceforitem.ItemID = item.ItemID
AND priceforitem.PriceID = ?PriceID
I already make it using the Method query but I don't know if it will produce the same result
db.Items
.GroupJoin(
db.PriceForItems.Where(pi => pi.PriceID == id),
i => i.ItemID,
pi => pi.ItemID,
(i, pi) => new { Item = b, Prices = pi })
.SelectMany(
a => a.Prices.DefaultIfEmpty(),
(i, pi) => new
{
ItemID = i.Item.ItemID,
Code = i.Item.Code,
Name = i.Item.Name,
PriceForItemID = pi.PriceForItemID,
Price = pi.Price
})
and then after thinking for awhile i shorten it like this
db.Items
.SelectMany(
i => db.PriceForItems.Where(
pi => pi.PriceID == id
&& pi.ItemID = i.ItemID).DefaultIfEmpty(),
(i, pi) => new
{
ItemID = i.Item.ItemID,
Code = i.Item.Code,
Name = i.Item.Name,
PriceForItemID = pi.PriceForItemID,
Price = pi.Price
})
I am new to Linq, and I don't know which is better and how to convert it to Linq query statement.
First of all your sql query. It is effectively and inner join because the where condition will filter out all rows where data from priceforitem is null. If you do want to convert same query to linq you can do it like
from i in db.Items
join p in db.PriceforItems on
i.ItemId equals p.ItemId into tempvals
from t in tempvals.DefaultIfEmpty()
where t.PriceId == id
select new{i.ItemId, ..., t.PriceId, t...., t....}
I mostly write linq queries instead of expressions where they are more readable to me. If you still want to get an expression, you can write a valid linq query and paste it into Linqpad and it will give the result as well as lambda expression of your query.

How can I sort by multiple fields in LINQ?

how can I do multiple sort in
return (from p in _db.Pages where p.int_PostStatusId == 2 select p).OrderByDescending(m => m.int_SortOrder);
i want to do order by by int_PageId as well? first by int_SortOrder then by int_PageId
Use either ThenBy or ThenByDescending to order the result of an OrderBy or OrderByDescending:
return (...)
.OrderByDescending(m => m.int_SortOrder)
.ThenBy(m => m.int_PageId);
Or using the query syntax:
orderby p.int_SortOrder descending, p.int_PageId

complex orderby that links to another table

I have the following query to start with:
var query = from p in db.Products
from pc in p.NpProductCategories
where pc.CategoryId == categoryId
select p;
I'm applying some more filtering on it and in the end I want to sort the results:
if (orderBy == ProductSortingEnum.Name)
query = query.OrderBy(x => x.Name);
else
query = query.OrderBy(............);
My big problem (coming from not knowing linq too good) is the ELSE here. How can I sort results by a column that is not in the current result set? I would like to somehow link to another linq query in the orderby. The sorting I'm trying to achive is to link to NpProductVariants query using the ProductId to match between NpProductVariant and Products
and sort by the Price of the NpProductVariant
Assuming you have the relationship set up in the dbml...
For one to one (and many to one):
query = query.OrderBy(p => p.NpProductVariant.Price);
For one to many:
query = query.OrderBy(p => p.NpProductVariants.Select(v => v.Price).Max());
Also:
var query =
from p in db.Products
where p.NpProductCategories.Any(pc => pc.CategoryId == categoryId)
select p;
I think you can hook your Join to your query as long as it is returning the same thing. So maybe something like (I'm not 100 % sure since I haven't tried it):
query = from i1 in query
join i2 in query2 on i1.PropertyToJoin equals i2.PropertyToJoin
orderby i1.OrderProp1, i2.OrderProp2
select i1;
But I think it might be a good idea to check the generated sql so it is still effective.

Resources