.NET Framework - Linq. Take and OrderBy

Asked By shapper
05-Sep-08 07:13 AM
Hello,

I have the following Linq Query:

viewData.TagsPapers = (from t in database.Tags
select new TagPaper {
Tag = t,
Count = t.PostsTags.Count
} into tp
where tp.Count != 0
orderby tp.Tag.Name, tp.Count
descending
select tp).Take(20).ToList();

I don't think this is making what I need.
I want to get the 20 records that have an higher value of tp.Count.
Then I need to order those 20 records by their tp.Tag.Name.

What am I doing wrong?

Thanks,
Miguel
LINQ
(1)
OrderBy
(1)
ToList
(1)
AsQueryable
(1)
Database
(1)
Console
(1)
Sort
(1)
Log
(1)
  Marc Gravell replied...
05-Sep-08 07:14 AM
Didn't we already discuss this? First, the early orderby should be
reversed: tp.Count, tp.Tag.Name
Also, at a minimum, you need to do the OrderBy(tp=>tp.Tag.Name)
*after* the Take(20).
If this doesn't work (i.e. it is incorrectly mangled into the query),
then re-order the list after retreiving it:

var list = {...}.ToList();

list.Sort((x,y) => string.Compare(x.Tag.Name, y.Tag.Name));

Marc
  Jon Skeet [C# MVP] replied...
05-Sep-08 07:14 AM
new TagPaper {
g =3D t,
unt =3D t.PostsTags.Count
tp
tp.Count !=3D 0
y tp.Tag.Name, tp.Count
tp).Take(20).ToList();

You need to order twice, so:
(from t in database.Tags
select new TagPaper {
Tag =3D t,
Count =3D t.PostsTags.Count
} into tp
where tp.Count !=3D 0
orderby tp.Count descending
select tp)
.Take(20)
.OrderBy(tp =3D> tp.Tag.Name)
.ToList();

Jon
  Marc Gravell replied...
05-Sep-08 07:14 AM
For info, I checked whether LINQ-to-SQL does it correctly, and it
seems to; using NWind:

ctx.Log = Console.Out;
var qry = (from order in ctx.Orders
orderby order.Freight, order.OrderID
select new {
Order = order,
Lines = order.Order_Details.Count() })
.Take(20)
.OrderBy(x => x.Order.OrderID)
.ToList();

gives TSQL as below; complex looking, but does what we want in the
right order...

Marc

SELECT [t3].[OrderID], [t3].[CustomerID], [t3].[EmployeeID], [t3].
[OrderDate], [
t3].[RequiredDate], [t3].[ShippedDate], [t3].[ShipVia], [t3].
[Freight], [t3].[Sh
ipName], [t3].[ShipAddress], [t3].[ShipCity], [t3].[ShipRegion], [t3].
[ShipPosta
lCode], [t3].[ShipCountry], [t3].[value] AS [Lines]
FROM (
SELECT TOP (20) [t2].[OrderID], [t2].[CustomerID], [t2].
[EmployeeID], [t2].[
OrderDate], [t2].[RequiredDate], [t2].[ShippedDate], [t2].[ShipVia],
[t2].[Freig
ht], [t2].[ShipName], [t2].[ShipAddress], [t2].[ShipCity], [t2].
[ShipRegion], [t
2].[ShipPostalCode], [t2].[ShipCountry], [t2].[value]
FROM (
SELECT [t0].[OrderID], [t0].[CustomerID], [t0].[EmployeeID],
[t0].[Order
Date], [t0].[RequiredDate], [t0].[ShippedDate], [t0].[ShipVia], [t0].
[Freight],
[t0].[ShipName], [t0].[ShipAddress], [t0].[ShipCity], [t0].
[ShipRegion], [t0].[S
hipPostalCode], [t0].[ShipCountry], (
SELECT COUNT(*)
FROM [dbo].[Order Details] AS [t1]
WHERE [t1].[OrderID] = [t0].[OrderID]
) AS [value]
FROM [dbo].[Orders] AS [t0]
) AS [t2]
ORDER BY [t2].[Freight], [t2].[OrderID]
) AS [t3]
ORDER BY [t3].[OrderID], [t3].[Freight]
  GlennFHenrikse replied...
05-Sep-08 06:10 AM
First you have to get the twenty items with the highest number, then you have
to order the list again.

A test I made:
var Tags = new[] {
new  { Name = "test1", Count=3 },
new  { Name = "test2", Count=7 },
new  { Name = "test3", Count=45 },
new  { Name = "test4", Count=1 },
new  { Name = "test5", Count=6 },
new  { Name = "test6", Count=34 },
new  { Name = "test7", Count=78 },
new  { Name = "test8", Count=32 },
new  { Name = "test9", Count=54 },
new  { Name = "test10", Count=67 },
new  { Name = "test11", Count=32 },
new  { Name = "test12", Count=63 },
new  { Name = "test13", Count=13 },
new  { Name = "test14", Count=86 },
new  { Name = "test15", Count=23 },
new  { Name = "test16", Count=36 },
new  { Name = "test17", Count=26 },
new  { Name = "test18", Count=67 },
}.AsQueryable();

var result = (from t in Tags
orderby t.Count descending
select t).Take(10).OrderBy(t => t.Name);

This one just takes 10 since I didn't want to make that many object.

So your thing would be someting like:


viewData.TagsPapers = (from t in database.Tags
orderby t.Count descending
select t).Take(20).OrderBy(t => t.Name);

If you are using LINQ to SQL it will create SQL similar to this
SELECT <fields>
FROM (
SELECT <fields>
FROM Tags
ORDER BY Count DESC
)
ORDER BY Name
--
Glenn F. Henriksen
http://www.henriksen.no/
  shapper replied...
07-Sep-08 11:44 AM
have
ding
erBy(t =3D> t.Name);
rderby t.Count descending
elect t).Take(20).OrderBy(t =3D> t.Name);

Thank you very much to all!

Cheers,
Miguel
  Guy replied...
05-Sep-08 01:43 PM
I see a lot of LINQ results using reflection to get values now a day. How
slow are these kind of late binding operation? Anyone has some scientific
comparison results.

Regards,



You need to order twice, so:
(from t in database.Tags
select new TagPaper {
Tag = t,
Count = t.PostsTags.Count
} into tp
where tp.Count != 0
orderby tp.Count descending
select tp)
.Take(20)
.OrderBy(tp => tp.Tag.Name)
.ToList();

Jon
  Marc Gravell replied...
07-Sep-08 11:45 AM
LINQ isn't necessarily using reflection; it can use dynamic methods to
use regular IL to access members. As for UI binding - that is going to
be the same either way. Even with untyped objects and no LINQ you can
speed things up *if* you know this is your bottleneck (bulk import/
export etc) - search for HyperDescriptor, for example.

In most cases, the work done in reflection is small in scope, and so
not a performance issue.

Marc
help
Linq-to-Sql var null question or observation .NET Framework This is more an observation than MyMatchingTables = null, but rather I get zero hits (or .Count = 0). Must be built into Linq-to-Sql. I have been using it for years but this is the first time RL public List<MyTable> GetMyTablesByName(string aString) { List<MyTable> myMyTableList = new List<MyTable> (); try { DataContext database = new DataContext(MyConnectionString); var MyMatchingTables = from X in db.MyTables where X.AField.StartsWith(aString) select X; / / why is var MyMatchingTables never null? Must be built into Linq to Sql to never return null? myMyTableList = MyMatchingTables ToList(); } catch (Exception ex) { Debug.WriteLine(ex.Message); / / never triggered, even if no match } return myMyTableList That's what is coming out of the query even if you did not use ToList(), an empty List<T> being created. Now if you were using First() or FirstorDefault(), the the point So this could return a var MyMatchingTables = 3D null? But I thought in Linq-to-Sql that is not allowed? So it will throw an exception (in the try a row out of the table encapsulated as an object / entity, as that is what Linq does. What is Language Integrated Query? LINQ is a Microsoft .NET Framework component that adds
Is Linq to SQL any good? .NET Framework I am a big fan of linq but in my opinion linq to sql is a complete waste of time. Why on earth take something that is difficult to write by creating a translation layer. I see people here struggling to write linq to sql queries. It also creates the problem of being locked into a particular product with regards to the database which is exactly the problem I thought a translation layer would be designed to solve 1) Entity Framework (1) Visual Studio (1) Silverlight (1) Oracle (1) If we ignore the LINQ to SQL vs LINQ to EF aspect. You should use LINQ to EF not LINQ to SQL. .NET wanted an ORM. Many people including me like
Linq vs Sprocs, Pros and Cons .NET Framework I should say from the outset that I haven't used Linq yet, but I know of it and its popularity. From a database point of view, I am thinking that the use of Linq can obscure the underlying access to the database and prohibit query optimisation that is key to attaining good performance. As the logic in the high-level language becomes more complex, so can the queries generated by Linq, to the point where speed can decline significantly. This has been my experience. On the writer of code primarily in a high-level language, I can see the attraction of Linq in obfuscating the data accees layer and allowing logic to be created using high-level would be very interested in people's views on the pros and cons of using Linq versus creating database sprocs and using simplified high-level logic. I have no axe to
linq versus BindingSource. .NET Framework Hello, I think that BindingSource is old fashion attitude. I use filter, I need to retrieve the table data). I want to change my code using linq instead. Before I change 100, 000 lines of code, I need to know whether the linq overcome the performance problems, and is linq indeed is the best way that good for convenience and also good for performance? Is not, what else can I use instead of using BindingSource? Also : Can I write into database via linq? (that is must). Thanks :) C# Discussions SQL Server (1) Entity Framework (1) IDbDataParameter (1) IDbDataAdapter other words, what are you binding to? Are you binding datatables or custom collections? What database are you using? Are you interested in Linq to Datasets, Linq to SQL, Linq to Objects, Linq to XML, or Linq to Entities
Linq to entites .NET Framework I have a 3 tables the lets call them A, B in C that link to a single row in A. How do I write the linq statement? Thanks ASP.NET Discussions SQL Server (1) Entity Framework (1) ADO.NET (1) LINQ (1) CJOIN (1) Database (1) ThatsIT (1) KwaZulu (1) http: / / codingsense.wordpress.com / 2009 / 03 / 08 / left-join-right join-using-linq / I suggest you get yourself a good book on Linq. _ __ __ __ __ _ Information from ESET NOD32 Antivirus, version of virus signature database 4537 (20091023) _ __ __ __ __ _ The message was checked by ESET NOD32 Antivirus. http: / / www.eset.com Ray Marron Hmm. . it just occurred to me that you may not have been using "linq" as a misspelled synonym for "join". If so, sorry - never used it. - - Ray Yes I