IEnumerable OrderBy on a text field
-
Hi, When I try...
people.OrderBy(name => name.Name);
I get...
ex = {"An order by expression can only contain non-constant scalars that are order comparable by the server. The expression with type 'Text' is not order comparable."}
Can I get IEnumerable OrderBy to sort on a text field, using a predicate perhaps? Thanks.
There must be some mistake in your code prior to your orderby call, as you should be able to order by text. As a quick demo I did this
public partial class Form1 : Form
{
List<Person> sortedPeople;public Form1() { InitializeComponent(); List<Person> people = new List<Person> {new Person("wayne"), new Person("sarah"), new Person("mark"), new Person("simon"), new Person("ashleigh"), new Person("dave"), new Person("connor"), new Person("bronwyn"), new Person("chantelle"), new Person("will"), new Person("chris")}; sortedPeople = people.OrderBy(name = name.Name).ToList(); } } class Person { public Person(string name) { this.Name = name; } public string Name { get; set; } }
and SortedPeople came out correctly
When I was a coder, we worked on algorithms. Today, we memorize APIs for countless libraries — those libraries have the algorithms - Eric Allman
-
Hi, When I try...
people.OrderBy(name => name.Name);
I get...
ex = {"An order by expression can only contain non-constant scalars that are order comparable by the server. The expression with type 'Text' is not order comparable."}
Can I get IEnumerable OrderBy to sort on a text field, using a predicate perhaps? Thanks.
Hi, try the below code snippet var newList = people.OrderBy(name => name.Name).ToList(); -Manognya __________________________________________________ $ God gives what is best.Not what all you wish :)
-
Hi, try the below code snippet var newList = people.OrderBy(name => name.Name).ToList(); -Manognya __________________________________________________ $ God gives what is best.Not what all you wish :)
Hi, thanks for looking at this. Not sure what I am doing wrong. I tried...
DataContext = new DataClasses1DataContext(); var people = from name in DataContext.Table\_Peoples where name.IQ < 3 select name; var peopleOrdered = people.OrderBy(name => name.Name).ToList();
'Name' is decared as follows...
[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Name", DbType="Text", UpdateCheck=UpdateCheck.Never)]
public string Name
{
get
{
return this._Name;
}
set
{
if ((this._Name != value))
{
this._Name = value;
}
}
}It is still thowing the same exception.
-
Hi, thanks for looking at this. Not sure what I am doing wrong. I tried...
DataContext = new DataClasses1DataContext(); var people = from name in DataContext.Table\_Peoples where name.IQ < 3 select name; var peopleOrdered = people.OrderBy(name => name.Name).ToList();
'Name' is decared as follows...
[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Name", DbType="Text", UpdateCheck=UpdateCheck.Never)]
public string Name
{
get
{
return this._Name;
}
set
{
if ((this._Name != value))
{
this._Name = value;
}
}
}It is still thowing the same exception.
Ok I got it to work like this...
DataContext = new DataClasses1DataContext(); var people = from name in DataContext.Table\_Peoples where name.IQ < 3 select name; List<Table\_People> listPeople = people.ToList(); var peopleOrdered = listPeople.OrderBy(name => name.Name).ToList();
But I dont understand why I have to copy to a List first?
-
Ok I got it to work like this...
DataContext = new DataClasses1DataContext(); var people = from name in DataContext.Table\_Peoples where name.IQ < 3 select name; List<Table\_People> listPeople = people.ToList(); var peopleOrdered = listPeople.OrderBy(name => name.Name).ToList();
But I dont understand why I have to copy to a List first?
Quote:
__John_ wrote:
List<Table_People> listPeople = people.ToList(); var peopleOrdered = listPeople.OrderBy(name => name.Name).ToList();
To order the list, it requires the set of names to be in a format and we are storing it as the enumerable list.
-Manognya __________________________________________________ $ God gives what is best.Not what all you wish :)
-
Quote:
__John_ wrote:
List<Table_People> listPeople = people.ToList(); var peopleOrdered = listPeople.OrderBy(name => name.Name).ToList();
To order the list, it requires the set of names to be in a format and we are storing it as the enumerable list.
-Manognya __________________________________________________ $ God gives what is best.Not what all you wish :)
-
Hi Manognya, I dont understand why List.OrderBy works when IEnumerable.OrderBy does not? I am not sure what you mean when you say 'in a format'? Thanks.
Hi John, The syntax of OrderBy is:
Public Shared Function OrderBy(Of TSource, TKey) ( _
source As IEnumerable(Of TSource), _
keySelector As Func(Of TSource, TKey) _
) As IOrderedEnumerable(Of TSource)Parameters
source
Type: System.Collections.Generic.IEnumerable(Of TSource)
A sequence of values to order.keySelector
Type: System.Func(Of TSource, TKey)
A function to extract a key from an element.we need to convert the source to be of type
System.Collections.Generic.IEnumerable
Hope this helps.
-Manognya __________________________________________________ $ God gives what is best.Not what all you wish :)
-
Hi Manognya, I dont understand why List.OrderBy works when IEnumerable.OrderBy does not? I am not sure what you mean when you say 'in a format'? Thanks.
Also, look at the link http://msdn.microsoft.com/en-us/library/bb534966.aspx#Y1297[^] Do not forget to vote the answer that serves the purpose ;)
-Manognya __________________________________________________ $ God gives what is best.Not what all you wish :)
-
Also, look at the link http://msdn.microsoft.com/en-us/library/bb534966.aspx#Y1297[^] Do not forget to vote the answer that serves the purpose ;)
-Manognya __________________________________________________ $ God gives what is best.Not what all you wish :)
-
Thanks, it is slowly becoming clear, I probably just need to think about it a bit more. I do sometimes find templates a bit confusing. +5
Agree..templates is always little tricky(for me either ;))...But, Once got..makes life easy:)
-Manognya __________________________________________________ $ God gives what is best.Not what all you wish :)
-
Ok I got it to work like this...
DataContext = new DataClasses1DataContext(); var people = from name in DataContext.Table\_Peoples where name.IQ < 3 select name; List<Table\_People> listPeople = people.ToList(); var peopleOrdered = listPeople.OrderBy(name => name.Name).ToList();
But I dont understand why I have to copy to a List first?
The difference is not the IEnumerable or the List but where the OrderBy take place. When you call ToList,or any greedy query operators, you execute your Ling query against your DB. After that, all Linq operation are executed in memory and Linq-to-object can do more things in than Linq-to-sql, or Linq-to-entities
Vince Remember the dead, fight for the living
-
The difference is not the IEnumerable or the List but where the OrderBy take place. When you call ToList,or any greedy query operators, you execute your Ling query against your DB. After that, all Linq operation are executed in memory and Linq-to-object can do more things in than Linq-to-sql, or Linq-to-entities
Vince Remember the dead, fight for the living
Thanks Vince, that explains it a bit more. I think i can now understand what the debuger is showing me. It uses a 'lazy' stratergy, ie. only evaluating an expression or executing a function when the result is actually needed, am I right? BTW: How can I enumerate the results more that once? Hoping that is not too stupid a question :doh: Thanks - John.
-
Thanks Vince, that explains it a bit more. I think i can now understand what the debuger is showing me. It uses a 'lazy' stratergy, ie. only evaluating an expression or executing a function when the result is actually needed, am I right? BTW: How can I enumerate the results more that once? Hoping that is not too stupid a question :doh: Thanks - John.
http://msdn.microsoft.com/en-us/library/s793z9y2.aspx[^]
You cannot set Current to the first element of the collection again; you must create a new enumerator instance instead.
Seems a strange way of going about things but I am sure there is a reason :confused:
-
Thanks Vince, that explains it a bit more. I think i can now understand what the debuger is showing me. It uses a 'lazy' stratergy, ie. only evaluating an expression or executing a function when the result is actually needed, am I right? BTW: How can I enumerate the results more that once? Hoping that is not too stupid a question :doh: Thanks - John.
__John_ wrote:
It uses a 'lazy' strategy, ie. only evaluating an expression or executing a function when the result is actually needed, am I right?
Yes you are right. It's a principle of Linq to defer execution until is needed. And Linq also evaluate only the elements needed to return the result Let's take Wayne List and do some examples
List peoples = new List {new Person("wayne"), new Person("sarah"), new Person("mark"), new Person("simon"), new Person("ashleigh"), new Person("dave"), new Person("connor"), new Person("bronwyn"), new Person("chantelle"), new Person("will"), new Person("chris")};
int Count = people.Count(p => p.Name.StartsWith("w")); //<-- Count is a greedy operator and all persons are evaluated for a result of 2.
var firstperson = people.Where(p => p.Name.Length == 5).Take(3);
foreach (var p in firstperson) // <-- evaluation start where and only Wayne, Sarah, Mark and Simon will be evaluated. The rest of the list is left alone
{
Console.WriteLine(p.Name);
}// And to show you when Linq expression are evaluated, try
var firstperson2 = people.Where(p => p.Name.Length == 5).Take(3);
people.Insert(1, new Person("Vince"));foreach (var p in firstperson) // <-- evaluation start where and only Wayne, Vince ans Sarah, will be evaluated. The rest of the list is left alone
{
Console.WriteLine(p.Name);
}http://blogs.msdn.com/b/charlie/archive/2007/12/09/deferred-execution.aspx[^]
__John_ wrote:
BTW: How can I enumerate the results more that once?
If you use a Enumerator, you can use Reset to set the enumerator to its initial position, which is before the first element in the collection. But if you use a foreach loop, you can reuse an Enumerable many times. The foreach loop will start at the beginning every time.
Vince Remember the dead, fight for the living
-
__John_ wrote:
It uses a 'lazy' strategy, ie. only evaluating an expression or executing a function when the result is actually needed, am I right?
Yes you are right. It's a principle of Linq to defer execution until is needed. And Linq also evaluate only the elements needed to return the result Let's take Wayne List and do some examples
List peoples = new List {new Person("wayne"), new Person("sarah"), new Person("mark"), new Person("simon"), new Person("ashleigh"), new Person("dave"), new Person("connor"), new Person("bronwyn"), new Person("chantelle"), new Person("will"), new Person("chris")};
int Count = people.Count(p => p.Name.StartsWith("w")); //<-- Count is a greedy operator and all persons are evaluated for a result of 2.
var firstperson = people.Where(p => p.Name.Length == 5).Take(3);
foreach (var p in firstperson) // <-- evaluation start where and only Wayne, Sarah, Mark and Simon will be evaluated. The rest of the list is left alone
{
Console.WriteLine(p.Name);
}// And to show you when Linq expression are evaluated, try
var firstperson2 = people.Where(p => p.Name.Length == 5).Take(3);
people.Insert(1, new Person("Vince"));foreach (var p in firstperson) // <-- evaluation start where and only Wayne, Vince ans Sarah, will be evaluated. The rest of the list is left alone
{
Console.WriteLine(p.Name);
}http://blogs.msdn.com/b/charlie/archive/2007/12/09/deferred-execution.aspx[^]
__John_ wrote:
BTW: How can I enumerate the results more that once?
If you use a Enumerator, you can use Reset to set the enumerator to its initial position, which is before the first element in the collection. But if you use a foreach loop, you can reuse an Enumerable many times. The foreach loop will start at the beginning every time.
Vince Remember the dead, fight for the living
-
__John_ wrote:
It uses a 'lazy' strategy, ie. only evaluating an expression or executing a function when the result is actually needed, am I right?
Yes you are right. It's a principle of Linq to defer execution until is needed. And Linq also evaluate only the elements needed to return the result Let's take Wayne List and do some examples
List peoples = new List {new Person("wayne"), new Person("sarah"), new Person("mark"), new Person("simon"), new Person("ashleigh"), new Person("dave"), new Person("connor"), new Person("bronwyn"), new Person("chantelle"), new Person("will"), new Person("chris")};
int Count = people.Count(p => p.Name.StartsWith("w")); //<-- Count is a greedy operator and all persons are evaluated for a result of 2.
var firstperson = people.Where(p => p.Name.Length == 5).Take(3);
foreach (var p in firstperson) // <-- evaluation start where and only Wayne, Sarah, Mark and Simon will be evaluated. The rest of the list is left alone
{
Console.WriteLine(p.Name);
}// And to show you when Linq expression are evaluated, try
var firstperson2 = people.Where(p => p.Name.Length == 5).Take(3);
people.Insert(1, new Person("Vince"));foreach (var p in firstperson) // <-- evaluation start where and only Wayne, Vince ans Sarah, will be evaluated. The rest of the list is left alone
{
Console.WriteLine(p.Name);
}http://blogs.msdn.com/b/charlie/archive/2007/12/09/deferred-execution.aspx[^]
__John_ wrote:
BTW: How can I enumerate the results more that once?
If you use a Enumerator, you can use Reset to set the enumerator to its initial position, which is before the first element in the collection. But if you use a foreach loop, you can reuse an Enumerable many times. The foreach loop will start at the beginning every time.
Vince Remember the dead, fight for the living
Nice examples - thanks!
When I was a coder, we worked on algorithms. Today, we memorize APIs for countless libraries — those libraries have the algorithms - Eric Allman
-
__John_ wrote:
It uses a 'lazy' strategy, ie. only evaluating an expression or executing a function when the result is actually needed, am I right?
Yes you are right. It's a principle of Linq to defer execution until is needed. And Linq also evaluate only the elements needed to return the result Let's take Wayne List and do some examples
List peoples = new List {new Person("wayne"), new Person("sarah"), new Person("mark"), new Person("simon"), new Person("ashleigh"), new Person("dave"), new Person("connor"), new Person("bronwyn"), new Person("chantelle"), new Person("will"), new Person("chris")};
int Count = people.Count(p => p.Name.StartsWith("w")); //<-- Count is a greedy operator and all persons are evaluated for a result of 2.
var firstperson = people.Where(p => p.Name.Length == 5).Take(3);
foreach (var p in firstperson) // <-- evaluation start where and only Wayne, Sarah, Mark and Simon will be evaluated. The rest of the list is left alone
{
Console.WriteLine(p.Name);
}// And to show you when Linq expression are evaluated, try
var firstperson2 = people.Where(p => p.Name.Length == 5).Take(3);
people.Insert(1, new Person("Vince"));foreach (var p in firstperson) // <-- evaluation start where and only Wayne, Vince ans Sarah, will be evaluated. The rest of the list is left alone
{
Console.WriteLine(p.Name);
}http://blogs.msdn.com/b/charlie/archive/2007/12/09/deferred-execution.aspx[^]
__John_ wrote:
BTW: How can I enumerate the results more that once?
If you use a Enumerator, you can use Reset to set the enumerator to its initial position, which is before the first element in the collection. But if you use a foreach loop, you can reuse an Enumerable many times. The foreach loop will start at the beginning every time.
Vince Remember the dead, fight for the living
Nice examples.Thanks.Its more clear now.
-Manognya __________________________________________________ $ God gives what is best.Not what all you wish :)