[c#]switch .OrderBy() efficienter?

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • mmniet
  • Registratie: Oktober 2002
  • Laatst online: 11-09 20:14

mmniet

De beetje weter

Topicstarter
Hallo,

Ik heb de volgende code geschreven
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
List<HotelService.DataAccess.Reservation> reservationList;
            switch (orderBy)
            { 
                case "ID":
                    if (sortOrder == "ascending") {reservationList = query_total.OrderBy(query => query.ID).Skip(skipCount).Take(countPerPage).ToList();}
                    else {reservationList = query_total.OrderByDescending(query => query.ID).Skip(skipCount).Take(countPerPage).ToList();}
                    break;
                case "name":
                    if (sortOrder == "ascending") {reservationList = query_total.OrderBy(query => query.Name).Skip(skipCount).Take(countPerPage).ToList(); }
                    else {reservationList = query_total.OrderByDescending(query => query.Name).Skip(skipCount).Take(countPerPage).ToList(); }
                    break;
                case "email":
                    if (sortOrder == "ascending") {reservationList = query_total.OrderBy(query => query.Email).Skip(skipCount).Take(countPerPage).ToList(); }
                    else {reservationList = query_total.OrderByDescending(query => query.Email).Skip(skipCount).Take(countPerPage).ToList(); }
                    break;
                case "hotelname":
                    if (sortOrder == "ascending") {reservationList = query_total.OrderBy(query => query.HotelID).Skip(skipCount).Take(countPerPage).ToList(); }
                    else {reservationList = query_total.OrderByDescending(query => query.HotelID).Skip(skipCount).Take(countPerPage).ToList(); }
                    break;
                case "roomtype":
                    if (sortOrder == "ascending") {reservationList = query_total.OrderBy(query => query.RoomTypeID).Skip(skipCount).Take(countPerPage).ToList(); }
                    else {reservationList = query_total.OrderByDescending(query => query.RoomTypeID).Skip(skipCount).Take(countPerPage).ToList(); }
                    break;
                case "checkin":
                    if (sortOrder == "ascending") {reservationList = query_total.OrderBy(query => query.CheckinTime).Skip(skipCount).Take(countPerPage).ToList(); }
                    else {reservationList = query_total.OrderByDescending(query => query.CheckinTime).Skip(skipCount).Take(countPerPage).ToList(); }
                    break;
                case "checkout":
                    if (sortOrder == "ascending") {reservationList = query_total.OrderBy(query => query.CheckoutTime).Skip(skipCount).Take(countPerPage).ToList(); }
                    else {reservationList = query_total.OrderByDescending(query => query.CheckoutTime).Skip(skipCount).Take(countPerPage).ToList(); }
                    break;
                case "numberofadult":
                    if (sortOrder == "ascending") {reservationList = query_total.OrderBy(query => query.NumberOfAdults).Skip(skipCount).Take(countPerPage).ToList(); }
                    else {reservationList = query_total.OrderByDescending(query => query.NumberOfAdults).Skip(skipCount).Take(countPerPage).ToList(); }
                    break;
                case "channel":
                    if (sortOrder == "ascending") {reservationList = query_total.OrderBy(query => query.Channel).Skip(skipCount).Take(countPerPage).ToList(); }
                    else {reservationList = query_total.OrderByDescending(query => query.Channel).Skip(skipCount).Take(countPerPage).ToList(); }
                    break;
                case "clientreference":
                    if (sortOrder == "ascending") {reservationList = query_total.OrderBy(query => query.ClientReference).Skip(skipCount).Take(countPerPage).ToList(); }
                    else {reservationList = query_total.OrderByDescending(query => query.ClientReference).Skip(skipCount).Take(countPerPage).ToList(); }
                    break;
                case "status":
                    if (sortOrder == "ascending") {reservationList = query_total.OrderBy(query => query.Status).Skip(skipCount).Take(countPerPage).ToList(); }
                    else {reservationList = query_total.OrderByDescending(query => query.Status).Skip(skipCount).Take(countPerPage).ToList(); }
                    break;
                default:
                    if (sortOrder == "ascending") {reservationList = query_total.OrderBy(query => query.Created).Skip(skipCount).Take(countPerPage).ToList(); }
                    else {reservationList = query_total.OrderByDescending(query => query.Created).Skip(skipCount).Take(countPerPage).ToList(); }
                    break;
            }


maar vind dit een grote lap tekst. Kan dit efficienter? Dus in de zin van
code:
1
query_total.OrderBy(query => <mijn-variabele-met-naam-kolom-als-waarde>)......


Heb gezocht op google, maar kwam vrijwel altijd de switch optie tegen, maar vind die niet zo heel prettig omdat dit veel code herhaling bevat.

It's me Mario


Acties:
  • 0 Henk 'm!

  • evolution536
  • Registratie: Maart 2009
  • Laatst online: 05-06-2024

evolution536

besh besh

Kun je me vertellen wat je met deze code wilt? Dat maakt het voor ons wat makkelijker om mee te denken.

Acties:
  • 0 Henk 'm!

  • asfaloth_arwen
  • Registratie: Februari 2005
  • Laatst online: 12:44
Zelf heb ik wel eens iets gebruikt op basis van: http://aonnull.blogspot.c...nq-orderby-extension.html

Specs


Acties:
  • 0 Henk 'm!

  • mmniet
  • Registratie: Oktober 2002
  • Laatst online: 11-09 20:14

mmniet

De beetje weter

Topicstarter
het gaat hier om het sorteren van een tabel na het klikken op een bepaalde kolom

It's me Mario


Acties:
  • 0 Henk 'm!

  • Pin0
  • Registratie: November 2002
  • Niet online
Als je je orderBy die je dus meegeeft hetzelfde noemt als je kolomnaam kan je dat dus als variabele in je query gebruiken (wel valideren!)
Kan dat niet dan zou je ook nog een array met een mapping oid. kunnen bijhouden met daarin de orderBy en de kolomnaam.

Mijn Lego Mocs - LEGO idea: The Motorcycle Garage


Acties:
  • 0 Henk 'm!

  • mmniet
  • Registratie: Oktober 2002
  • Laatst online: 11-09 20:14

mmniet

De beetje weter

Topicstarter
maar hoe gebruik je dan die variabele naam? ik krijg het niet voor elkaar

It's me Mario


Acties:
  • 0 Henk 'm!

  • D-Raven
  • Registratie: November 2001
  • Laatst online: 10-09 20:32
Je zou een dictionary kunnen gebruiken als mapping, waarin je de key als column naam hebt en een Action<T> als value.

Dan kun je dus zoiets doen:

C#:
1
2
3
4
mappingDict["status"](reservationList);

//waar de value dus iets als dit is
var statusActionVoorbeeld = new Action<List<vaniets>>(l => l.Orderby(x => x.status));

Acties:
  • 0 Henk 'm!

  • RayNbow
  • Registratie: Maart 2003
  • Laatst online: 12:39

RayNbow

Kirika <3

D-Raven schreef op dinsdag 20 december 2011 @ 09:10:
Je zou een dictionary kunnen gebruiken als mapping, waarin je de key als column naam hebt en een Action<T> als value.
In plaats van Action<T> kun je er ook Func<Reservation, object> instoppen:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
class Reservation
{
    public int ID;
    public string Name;
    public string Email;

    public override string ToString()
    {
        return string.Format("Reservation({0}, {1}, {2})", ID, Name, Email);
    }
}

class Program
{
    static void Main(string[] args)
    {
        var reservationList = new List<Reservation> {
            new Reservation() {ID = 3, Name = "Three", Email = "foo@bar.org"},
            new Reservation() {ID = 4, Name = "Four",  Email = "bar@123.org"},
            new Reservation() {ID = 5, Name = "Five",  Email = "rab@oof.org"},
        };

        var sortOrder = "descending";
        var orderBy = "name";
        var skipCount = 0;
        var countPerPage = 100;

        // deze dict vervangt in feite de switch
        var columns = new Dictionary<string, Func<Reservation, object>>() {
            {"ID",    x => x.ID},
            {"name",  x => x.Name},
            {"email", x => x.Email},
        };

        reservationList =
            (sortOrder == "ascending"
                ? reservationList.OrderBy(columns[orderBy])
                : reservationList.OrderByDescending(columns[orderBy])
            )
            .Skip(skipCount)
            .Take(countPerPage)
            .ToList();

        PrintIEnumerable(reservationList);
        Console.ReadKey();
    }

    static void PrintIEnumerable<T>(IEnumerable<T> xs)
    {
        var s = String.Join(",\n", xs.ToArray());
        Console.WriteLine(s);
    }
}

Ipsa Scientia Potestas Est
NNID: ShinNoNoir


Acties:
  • 0 Henk 'm!

  • D-Raven
  • Registratie: November 2001
  • Laatst online: 10-09 20:32
RayNbow schreef op dinsdag 20 december 2011 @ 09:22:
[...]


In plaats van Action<T> kun je er ook Func<Reservation, object> instoppen:
...
// deze dict vervangt in feite de switch
var columns = new Dictionary<string, Func<Reservation, object>>() {
{"ID", x => x.ID},
{"name", x => x.Name},
{"email", x => x.Email},
};

..
Dit gaat voor problemen zorgen zodra je op deze manier een DateTime wilt gaan sorten.

Acties:
  • 0 Henk 'm!

  • RayNbow
  • Registratie: Maart 2003
  • Laatst online: 12:39

RayNbow

Kirika <3

D-Raven schreef op dinsdag 20 december 2011 @ 09:54:
[...]

Dit gaat voor problemen zorgen zodra je op deze manier een DateTime wilt gaan sorten.
Op welke manier gaat dat fout dan?

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
class Reservation
{
    public int ID;
    public string Name;
    public string Email;

    public DateTime CreationDate;

    public override string ToString()
    {
        return string.Format("Reservation({0}, {1}, {2}, {3})", ID, Name, Email, CreationDate);
    }
}

class Program
{
    static void Main(string[] args)
    {
        var reservationList = new List<Reservation> {
            new Reservation() {ID = 3, Name = "Three", Email = "foo@bar.org", 
                                CreationDate = DateTime.Now},
            new Reservation() {ID = 4, Name = "Four",  Email = "bar@123.org",
                                CreationDate = DateTime.Parse("01-01-2010")},
            new Reservation() {ID = 5, Name = "Five",  Email = "rab@oof.org",
                                CreationDate = DateTime.Parse("12-12-2009")},
        };

        var sortOrder = "descending";
        var orderBy = "";
        var skipCount = 0;
        var countPerPage = 100;


        // switch:
        var defaultColumn = "date";
        var columns = new Dictionary<string, Func<Reservation, object>>() {
            {"ID",    x => x.ID},
            {"name",  x => x.Name},
            {"email", x => x.Email},
            {"date", x => x.CreationDate},
        };
        var orderByFunc = columns[defaultColumn];
        if (columns.ContainsKey(orderBy))
            orderByFunc = columns[orderBy];
            
        reservationList =
            (sortOrder == "ascending"
                ? reservationList.OrderBy(orderByFunc)
                : reservationList.OrderByDescending(orderByFunc)
            )
            .Skip(skipCount)
            .Take(countPerPage)
            .ToList();

        PrintIEnumerable(reservationList);
        Console.ReadKey();
    }

    static void PrintIEnumerable<T>(IEnumerable<T> xs)
    {
        var s = String.Join(",\n", xs.ToArray());
        Console.WriteLine(s);
    }
}

Ipsa Scientia Potestas Est
NNID: ShinNoNoir


Acties:
  • 0 Henk 'm!

  • mmniet
  • Registratie: Oktober 2002
  • Laatst online: 11-09 20:14

mmniet

De beetje weter

Topicstarter
ik heb de manier van RayNbow toegepast en werkt perfect! ook op datetimes :).

toppie en bedankt! Helder en goed voorbeeld! Kudo's!

It's me Mario


Acties:
  • 0 Henk 'm!

  • Sebazzz
  • Registratie: September 2006
  • Laatst online: 06:48

Sebazzz

3dp

Ik zou een Expression<Func<Reservation, object>> gebruiken. Waarom? Omdat je met de Func<Reservation, object> Enumerable.OrderBy aanroept en met Expression<Func<Reservation, object>> Queryable.OrderBy. In de praktijk betekent dit dat het ene via code werkt, en het andere via SQL/Database.

[Te koop: 3D printers] [Website] Agile tools: [Return: retrospectives] [Pokertime: planning poker]


Acties:
  • 0 Henk 'm!

  • D-Raven
  • Registratie: November 2001
  • Laatst online: 10-09 20:32
RayNbow schreef op dinsdag 20 december 2011 @ 10:40:
[...]

Op welke manier gaat dat fout dan?

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
class Reservation
{
    public int ID;
    public string Name;
    public string Email;

    public DateTime CreationDate;

    public override string ToString()
    {
        return string.Format("Reservation({0}, {1}, {2}, {3})", ID, Name, Email, CreationDate);
    }
}

class Program
{
    static void Main(string[] args)
    {
        var reservationList = new List<Reservation> {
            new Reservation() {ID = 3, Name = "Three", Email = "foo@bar.org", 
                                CreationDate = DateTime.Now},
            new Reservation() {ID = 4, Name = "Four",  Email = "bar@123.org",
                                CreationDate = DateTime.Parse("01-01-2010")},
            new Reservation() {ID = 5, Name = "Five",  Email = "rab@oof.org",
                                CreationDate = DateTime.Parse("12-12-2009")},
        };

        var sortOrder = "descending";
        var orderBy = "";
        var skipCount = 0;
        var countPerPage = 100;


        // switch:
        var defaultColumn = "date";
        var columns = new Dictionary<string, Func<Reservation, object>>() {
            {"ID",    x => x.ID},
            {"name",  x => x.Name},
            {"email", x => x.Email},
            {"date", x => x.CreationDate},
        };
        var orderByFunc = columns[defaultColumn];
        if (columns.ContainsKey(orderBy))
            orderByFunc = columns[orderBy];
            
        reservationList =
            (sortOrder == "ascending"
                ? reservationList.OrderBy(orderByFunc)
                : reservationList.OrderByDescending(orderByFunc)
            )
            .Skip(skipCount)
            .Take(countPerPage)
            .ToList();

        PrintIEnumerable(reservationList);
        Console.ReadKey();
    }

    static void PrintIEnumerable<T>(IEnumerable<T> xs)
    {
        var s = String.Join(",\n", xs.ToArray());
        Console.WriteLine(s);
    }
}
Ik zou verwachten dat datums nu alfanumeriek vergeleken worden. Maar ik hebt mis. Spoke to soon :P

Ook al is het return type Object, blijkbaar word er nog steeds gekeken naar IComparable interface e.d.

Acties:
  • 0 Henk 'm!

  • RayNbow
  • Registratie: Maart 2003
  • Laatst online: 12:39

RayNbow

Kirika <3

D-Raven schreef op dinsdag 20 december 2011 @ 12:49:
[...]

Ik zou verwachten dat datums nu alfanumeriek vergeleken worden. Maar ik hebt mis. Spoke to soon :P

Ook al is het return type Object, blijkbaar word er nog steeds gekeken naar IComparable interface e.d.
De OrderBy extension method legt geen restricties op het returntype van de meegegeven functie:
C#:
1
2
3
4
public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(
    this IEnumerable<TSource> source,
    Func<TSource, TKey> keySelector
)

Zoals hierboven te zien wordt TKey verder nergens gebruikt. De documentatie vertelt trouwens dat de comparer wordt opgevraagd via de Comparer<TKey>.Default property.

Ipsa Scientia Potestas Est
NNID: ShinNoNoir

Pagina: 1