LINQ difference OrderBy x.field descending versus OrderByDescending(x=>x.field) - linq

In order to make pagination, I need to order a query list, then take nSize elements skipping nFrom first
I wonder if, from the performance point of view, it's the same ordering by the clause orderby in the query, like this
IList<Product> resul = (
from m in db.Products()
where m.CategoryId==cId
orderby m.Name descending
select m
).Skip(nFrom).Take(nSize).ToList();
or ordering the results, like this
IList<Product> resul = (
from m in db.Products()
where m.CategoryId==cId
select m
).OrderByDescending(m=>m.Name).Skip(nFrom).Take(nSize).ToList();
I guess LINQ makes the same in both cases, but I need make sure in order to use the second option so I can parameterize the order field.

Related

Using TOP in ORACLE SQL 9

Hello I'am very new to writing SQL and I am trying to find the appropriate way to use TOP in Oracle SQl 9:
My example:
select * from example e, test t
where e.id = t.id
and country = 'USA'
order by state ASC;
What I am trying to do is take the bottom 20 % of my query but I know you cannot use TOP. After researching I still have not found an applicable answer. I know you have to first order them but am unsure of how to then take the bottom 20%(which would be TOP since the order is ASC)
In general (like if you want the top or bottom 17.2% of the rows) you can use row_number() and count() (analytic functions) to get the result.
20% is easier - you are looking for the top (or bottom) quintile. For this, you can use the ntile() function, like so:
select [column_names]
from (
select e.*, t.*, ntile(5) over (order by state) as nt
from ..... etc
)
where nt = 1;
The subquery is your query. The column_names in the outer query are whatever you actually need; you could also use select * but that will show the ntile too (which will be 1 in all rows).
If sorting something in ASCending order gives us the top set then surely sorting in DESCending order can give us the bottom set.
This solution uses the function NTILE() to divide the records into five buckets. The first bucket is the set we want (because sorted in descending order). Sorting in ascending order and taking the fifth quintile would have the same outcome.
select * from (
select e.*
, t.*
, ntile(5) over (order by state desc) nt
from example e, test t
where e.id = t.id
and country = 'USA'
)
where nt = 1
order by state desc
/
You don't say what your sort criteria are, so I've guessed.

Unable to use order by in sub query in HQL

I have this HQL where I need a subquery. I know it's not legal to make a subquery in order by, but I can't figure out how to do it
SELECT OBJECT(l) FROM InboundNotification l
INNER JOIN l.item item
WHERE l.job = ? ORDER BY (SELECT SUM(itemInst.qty)
FROM ItemInst itemInst
WHERE itemInst.receivedFromNotification_id = l.id) DESC, item.localId DESC
The above fails since I have the subquery in order by. How can I reconfigure it so this will work?
A sort in the Java code is not a option here even though it's almost as efficient.
ok, i haven't a notion of hql, but I'm gonna assume it's something like other query languages dive in here given that this question has remained unanswered for so long.
could you rewrite the query so it's something like this:
SELECT OBJECT(l), SUM(itemInst.qty) theSum
FROM InboundNotification l
INNER JOIN l.item item WHERE l.job = ?
INNER JOIN ItemInst on ItemInst.KEY = l.KEY
WHERE itemInst.receivedFromNotification_id = l.id)
GROUP BY OBJECT(l)
ORDER BY theSum
where ItemInst.KEY = l.KEY shows the appropriate relationship for your situation (if such a relationship exists)

Linq: Orderby when including multiple tables

Currently learning Linq to Entity. I been successful, but came stumped with the orderby clause and its use with multiple tables.
var query = from k in contxt.pages.Include("keywords")
where k.ID == vals.pageId select k;
My understanding with the code above is it creates an inner join where ID is equal to pageId.
So what I am having a difficult time visualizing is how I would perform an orderby on both tables?
I would like to sort on both tables.
I have tried:
var query = from k in contxt.pages.Include("keywords") where k.ID == vals.pageId orderby k.keywords.**?** select k;
The question mark is not supposed to be there. I am showing that the column that I would like to sort by isn't there. Trying this k.Kegwords. doesn't show the column.
I would write a SQL query as follows:
string query = "SELECT pages.page, pages.title, pages.descp, keywords.keyword
FROM pages INNER JOIN keywords ON pages.ID = keywords.pageID
ORDER BY keywords.sort, pages.page";
pages and keywords have a 1 to many relationship, which FK keywords.
Thank you,
deDogs
Here you go.
var result = (from x in pages
join y in keywords on x.ID equals y.pageID
orderby y.sort, x.page
select new
{
x.Page,
x.title,
x.descp,
y.keyword
});

Linq join with an inner collection

I am trying a LINQ to Object query on 2 collections
Customer.Orders
Branches.Pending.Orders (Collection within a collection)
I want to output each branch which is yet to deliver any order of the customer.
var match = from order in customer.Orders
join branch in Branches
on order equals branch.Pending.Orders
select branch;
This does not work, I get :
The type of one of the expressions in the join clause is incorrect. Type inference failed in the call to 'GroupJoin'.
From my search, I think this is because Order or collection of Orders does not implement equals.
If this query worked, it will still be wrong, as it will return a branch if the customer's and pending orders match exactly. I want a result if any of the order matches.
I am learning Linq, and looking for a approach to address such issues, rather than the solution itself.
I would have done this in SQL like this;
SELECT b.branch_name from Customers c, Branches b, Orders o
WHERE c.customer_id = o.customer_id
AND o.branch_id = b.branch_id
AND c.customer_id = 'my customer'
AND o.order_status = 'pending'
Looking at your Linq, you want something like this
var match =
from o in customer.Orders
from b in Branches
where b.Pending.Orders.FirstOrDefault(p => o.order_id == p.order_id) != null
select b;

Linq to SQL: order by value in related table

I have 2 tables which in simplified form look like this:
Products(
id: int,
name: varchar
);
ProductSpecs(
product_id: int,
spec_name: varchar,
spec_value: int
);
Now I need to sort products (in linq to sql) by value of some specification item (eg. "price"). So I do something like this
var products = from p in db.Products
from ps in p.ProductsSpecs
where ps.spec_name == "price"
orderby ps.spec_value
select p;
The problem is that if there's no such ProductSpec with spec_name "price" the product is not included at all. I can add these products with Union or Concat but this way the sorting of the first part is not preserved.
What is the best way to deal with this?
Thanks.
First, I would recommend that you either do this in pure SQL as a function or Stored Procedure and then access this through linq, or add a price column to your product table. It seems like price would be a normal attribute to add to all of your products even if that price is NULL.
SQL:
select p.*
from products p
left outer join productspecs ps on
p.id = ps.product_id
and ps.spec_name = 'Price'
order by ps.spec_value
With that said, here's the weird bit of LINQ that should work on your table (I might have some of the column names spelled incorrectly):
var products = from p in db.Products
join ps in (from pss in db.ProductSpecs
where pss.spec_name== "Price"
select pss
) on p.id equals ps.product_id into temp
from t in temp.DefaultIfEmpty()
orderby t.spec_value
select p;
I tested this on some tables setup like above and created 5 products, three with prices in different value orders and this LINQ ordered them just like the SQL above and returned the null result rows as well.
Hope this works!
In ordinary SQL, you'd use an LEFT OUTER JOIN. This preserves rows that appear in the left-hand table (the one listed first), even when there's no matching row in the right-hand table (the second one listed, and the one that is outer joined). You end up with nulls for the values that should be, but weren't, present in the right-hand table. So, the price for those items missing a price would appear as NULL.
What that translates to in LINQ to SQL is another matter.
You might care to think about whether it is reasonable to have products that do not have a price. You're emulating something called EAV - Entity, Attribute, Value - tables, and they are generally regarded as 'not a good thing'.
Can you not just do a simple join?
var products =
from p in db.Products
join ps in db.ProductSpecs on p.id equals ps.product_id
where ps.spec_name == "price"
orderby ps.spec_value
select p;

Resources