LINQ: Dynamic Order By clause

  • Follow


Hi,

I'd like to order a query either by an Integer value or a String value.
I could write

     select case condition
     case 1
        dim q = from bla in blub order by bla.IntegerProperty
     case 2
        dim q = from bla in blub order by bla.StringProperty
     end select

This is of no use because I have to access q after "end select". But
if I declared it before "select case", I'd have to write

     dim q as IOrderedEnumerable(Of TElement)

However, "TElement" is an anonymous type, so I can't do this also.

Is it possible to use a Comparer with the Order By clause anyhow?
Or, instead, can I achieve my goal by directly calling the extension method
System.Linq.Enumerable.OrderBy(Of TSource, TKey) anyhow?
In whichever direction I think, I always need the anonymous type. Probably
I do not and it's very simple, actually. Anybody's got a suggestion?


--
Armin



0
Reply Armin 1/7/2010 1:43:51 AM

 AZ>      select case condition
 AZ>      case 1
 AZ>         dim q = from bla in blub order by bla.IntegerProperty
 AZ>      case 2
 AZ>         dim q = from bla in blub order by bla.StringProperty
 AZ>      end select

I'm not familiar with linq, but just as an idea  from sql area that may be 
useful here: you can do something like this in sql:

select column1 from table
order by
    case
        when column2='a' then column3
        when column2='b' then column4
        else column5
    end

0
Reply Vadim 1/7/2010 4:47:04 AM


Armin Zingler wrote:
> Hi,
> 
> I'd like to order a query either by an Integer value or a String value.
> I could write
> 
>      select case condition
>      case 1
>         dim q = from bla in blub order by bla.IntegerProperty
>      case 2
>         dim q = from bla in blub order by bla.StringProperty
>      end select
> 
> This is of no use because I have to access q after "end select". But
> if I declared it before "select case", I'd have to write
> 
>      dim q as IOrderedEnumerable(Of TElement)
> 
> However, "TElement" is an anonymous type, so I can't do this also.
> 
> Is it possible to use a Comparer with the Order By clause anyhow?
> Or, instead, can I achieve my goal by directly calling the extension method
> System.Linq.Enumerable.OrderBy(Of TSource, TKey) anyhow?
> In whichever direction I think, I always need the anonymous type. Probably
> I do not and it's very simple, actually. Anybody's got a suggestion?
> 
> 
> --
> Armin
> 
> 
> 

You should pull the data 'q' with no order by

This is C# example as close as I can get it. I don't have code in front 
of me.

var a = q.orderacending(b => b.Property).Tolist();


I don't know if you have Lambda statement in VB.
0
Reply Mr 1/7/2010 5:06:32 AM

Armin Zingler wrote:
> Hi,
> 
> I'd like to order a query either by an Integer value or a String value.
> I could write
> 
>      select case condition
>      case 1
>         dim q = from bla in blub order by bla.IntegerProperty
>      case 2
>         dim q = from bla in blub order by bla.StringProperty
>      end select
> 
> This is of no use because I have to access q after "end select". But
> if I declared it before "select case", I'd have to write
> 
>      dim q as IOrderedEnumerable(Of TElement)
> 
> However, "TElement" is an anonymous type, so I can't do this also.
> 
> Is it possible to use a Comparer with the Order By clause anyhow?
> Or, instead, can I achieve my goal by directly calling the extension method
> System.Linq.Enumerable.OrderBy(Of TSource, TKey) anyhow?
> In whichever direction I think, I always need the anonymous type. Probably
> I do not and it's very simple, actually. Anybody's got a suggestion?
> 
> 
> --
> Armin
> 
> 
> 

You should pull the data 'q' with no order by

This is C# example as close as I can get it. I don't have code in front 
of me.

var a = q.orderacending(b => b.Property).Tolist();


I don't know if you have Lambda statement in VB.
0
Reply Mr 1/7/2010 5:09:20 AM

> I don't know if you have Lambda statement in VB.

2010 
0
Reply Cor 1/7/2010 6:14:52 AM

Mr. Arnold schrieb:
> You should pull the data 'q' with no order by
> 
> This is C# example as close as I can get it. I don't have code in front 
> of me.
> 
> var a = q.orderacending(b => b.Property).Tolist();
> 
> 
> I don't know if you have Lambda statement in VB.

I'm afraid, I can't read and translate this sCrabble# code. Thx anyway.


-- 
Armin
0
Reply Armin 1/7/2010 8:14:22 AM

Cor Ligthert[MVP] schrieb:
>> I don't know if you have Lambda statement in VB.
> 
> 2010 

It is 2010. ;)

-- 
Armin

0
Reply Armin 1/7/2010 8:15:04 AM

"Armin Zingler" wrote
>
> I'd like to order a query either by an Integer value or a String value.

Have you considered the LINQ Dynamic Query Library?

http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

Andrew 

0
Reply Andrew 1/7/2010 9:45:01 AM

Armin Zingler schrieb:
> Hi,
> 
> I'd like to order a query either by an Integer value or a String value.
> I could write
> 
>      select case condition
>      case 1
>         dim q = from bla in blub order by bla.IntegerProperty
>      case 2
>         dim q = from bla in blub order by bla.StringProperty
>      end select
> 
> This is of no use because I have to access q after "end select". But
> if I declared it before "select case", I'd have to write
> 
>      dim q as IOrderedEnumerable(Of TElement)
> 
> However, "TElement" is an anonymous type, so I can't do this also.
> 
> Is it possible to use a Comparer with the Order By clause anyhow?
> Or, instead, can I achieve my goal by directly calling the extension method
> System.Linq.Enumerable.OrderBy(Of TSource, TKey) anyhow?
> In whichever direction I think, I always need the anonymous type. Probably
> I do not and it's very simple, actually. Anybody's got a suggestion?

I got a reply (in the German group) that solves the problem. It says:

      dim q = from bla in blub

      select case condition
      case 1
         q = from bla in q order by bla.IntegerProperty
      case 2
         q = from bla in q order by bla.StringProperty
      end select

      'access q here

The trick is to assign the second query to the same variable as the first
one. Before, I wanted to assign it to another variable (q2) which created
the question of how to declare it.

Thx anyway for reading and replying.


-- 
Armin

0
Reply Armin 1/7/2010 9:50:28 AM

Andrew Morton schrieb:

> Have you considered the LINQ Dynamic Query Library?

Not yet, but I'll have a look. Thanks.

> http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx


-- 
Armin

0
Reply Armin 1/7/2010 11:07:13 AM

On 2010-01-07, Armin Zingler <az.nospam@freenet.de> wrote:
> Mr. Arnold schrieb:
>> You should pull the data 'q' with no order by
>> 
>> This is C# example as close as I can get it. I don't have code in front 
>> of me.
>> 
>> var a = q.orderacending(b => b.Property).Tolist();
>> 
>> 
>> I don't know if you have Lambda statement in VB.
>
> I'm afraid, I can't read and translate this sCrabble# code. Thx anyway.
>
>

I think the Mr. Arnold was implying something like this:

Option Explicit On
Option Strict On
Option Infer On

Module Module1
	Dim rnd As New Random

    Sub Main()
        Dim lst As New List(Of TestClass)

        For i As Integer = 1 To 100
            lst.Add(New TestClass(rnd.Next(1, 101), Chr(rnd.Next(65, 91))))
        Next

        Dim orderByInt As Func(Of TestClass, Integer) = Function(x As TestClass) x.I
        Dim orderByString As Func(Of TestClass, String) = Function(x As TestClass) x.S

        Dim q As IEnumerable(Of TestClass) = From t In lst Select t

        Console.WriteLine("========================   Order By Int ================")
        For Each t In q.OrderBy(orderByInt)
            Console.WriteLine("{0} : {1}", t.I, t.S)
        Next
        Console.ReadLine()
        Console.WriteLine("========================   Order By string ================")
        For Each t In q.OrderBy(orderByString)
            Console.WriteLine("{0} : {1}", t.I, t.S)
        Next

    End Sub

    Public Class TestClass
        Public I As Integer
        Public S As String

        Public Sub New(ByVal i As Integer, ByVal s As String)
            Me.I = i
            Me.S = s
        End Sub
    End Class
End Module

HTH
-- 
Tom Shelton
0
Reply Tom 1/7/2010 2:11:19 PM

Tom Shelton schrieb:
> 
> I think the Mr. Arnold was implying something like this:
> 
> Option Explicit On
> Option Strict On
> Option Infer On
> 
> [...]

Just wanted to say thank you so far only in the meantime because I haven't
read/tried it yet because the problem has been solved as mentioned in my other
replay.


--
Armin
0
Reply Armin 1/10/2010 9:53:03 AM

11 Replies
733 Views

(page loaded in 8.019 seconds)


Reply: