Jak sprytnie zapakować metodę w typ

0

cześć

Mam taki kod:

public enum SortingOption
    {
        AZ,
        ZA,
        PriceDescending,
        PriceAscending
    }

i teraz chciałbym na podstawie tego enuma pozyskać odpowiednią funkcję sortującą, czyli coś w tym stylu:

private Func<Product, string> GetSortingFunc(SortingOption sortingOption)
        {
            switch (sortingOption)
            {
                case SortingOption.AZ:
                    return product => product.Name;
                    
                case SortingOption.ZA:
                    break;
                case SortingOption.PriceDescending:
                    return product => product.Price;

                case SortingOption.PriceAscending:
                    break;
                default:
                    break;
            }
        }

Tutaj pojawia się problem taki, że sortowanie po cenie wymaga Func z typem decimal, a po nazwie z typem string... Kolejny problem to rozróżnienie sortowania rosnąco i malejąco - musiałbym zwracać metodę Linq OrderBy lub OrderByDescending ale jak to zrobić zeby zwracać cos w stylu OrderByDescending(product => product.Price? Ostatecznie miałoby to wyglądać tak:

        private ???? GetSortingFunc(SortingOption sortingOption)
        {
            switch (sortingOption)
            {
                case SortingOption.AZ:
                    return OrderBy(product => product.Name);
                    
                case SortingOption.ZA:
                    return OrderByDescending(product => product.Name);

                case SortingOption.PriceDescending:
                    return OrderBy(product => product.Price);

                case SortingOption.PriceAscending:
                    return OrderByDescending(product => product.Price);

                default:
                    break;
            }
        }
0

Tez o tym myslalem, ale wczesniej wywołuje na obiekcie repozytorium kilka innych metod jak Where,Select,Take,Skip i chcialbym do tego po prostu dodać odpowiednią funkcje sortującą. Przy wykorzystaniu wzorca musiałbym przesłać do strategii cały obiekt repozytorium tylko po to, żeby wykonać na nim sortowanie... Słabe :(

0

wymyśliłem cos co spełnia moje poczucie sprytności:

public static IOrderedEnumerable<Product> SortBy(this IEnumerable<Product> products, SortingOption sortingOption)
        {
            switch (sortingOption)
            {
                case SortingOption.AZ:
                    return products.OrderBy(p => p.Name);

                case SortingOption.ZA:
                    return products.OrderByDescending(p => p.Name);

                case SortingOption.PriceAscending:
                    return products.OrderBy(p => p.Price);

                case SortingOption.PriceDescending:
                    return products.OrderByDescending(p => p.Price);

                default:
                    return null;
            }
        }

jakby ktos mial lepszy pomysł to chetnie poznam

0

Może powiedz co chcesz konkretnie osiągnąć bo ten kod wygląda śmierdząco. Co jak będziesz potrzebował posortować po cenie a potem po nazwie ? Co jak dojdzie pole do modelu ? Dodać następnego enuma ? Do doprowadzi do tragedii za jakiś czas :D Dla zamówień też stworzysz identyczną metodę ?

0
error91 napisał(a):

Może powiedz co chcesz konkretnie osiągnąć bo ten kod wygląda śmierdząco. Co jak będziesz potrzebował posortować po cenie a potem po nazwie ? Co jak dojdzie pole do modelu ? Dodać następnego enuma ? Do doprowadzi do tragedii za jakiś czas :D Dla zamówień też stworzysz identyczną metodę ?

W 1 poscie wytlumaczylem co chce zrobic: posortowac repo na podstawie Enuma SortingOption.

Co jak będziesz potrzebował posortować po cenie a potem po nazwie ?

Nie rozumiem o co ci chodzi. Towar sortuje po cenie LUB po nazwie, nie ma znaczenia tutaj kolejnosc.

Co jak dojdzie pole do modelu
Jeśli dojdzie np pole IsOnStock, dodam do enuma taka wartosc i do mojej metody np products.Where(p => p.IsOnStock), nie ma problemu

Dla zamówień też stworzysz identyczną metodę ?

Nie mam jeszcze zamówień i nie pomyślałem o tym, ale pewnie będe się starał zrobić tą metodę generyczną, działającą dla Produktów i Zamówień

1

Jak rozumiem, to leci do bazy? jeżeli tak, to lepiej sprawdź jak to się wykona pod spodem :D

0
WeiXiao napisał(a):

Jak rozumiem, to leci do bazy? jeżeli tak, to lepiej sprawdź jak to się wykona pod spodem :D

Nie leci do bazy. Po co w ogóle sortować dane przed zapisaniem do bazy? To jest pobieranie danych z bazy i prezentowanie ich klientowi

1

A kto tu mówi o sortowaniu przed zapisem ? Jeśli budujesz z tego LINQ i działasz na IQueryable to to poleci do bazy. W innym wypadku posortujesz to w pamięci.

1
Trzeźwy Pomidor napisał(a):

To jest pobieranie danych z bazy i prezentowanie ich klientowi

Jak chcesz prezentować, to po co Ci w ogóle jakieś repozytorium? Nie do tego służy ten wzorzec.

Powinieneś mieć metodę, która zwraca Expression, tak aby mogła zostać wydajnie przetworzona przez ORM na sensowny SQL. Pobieranie całej bazy, jak to robisz teraz, nie jest raczej dobrym pomysłem. A poza tym, czy ten enum jest w ogóle dobrym pomysłem? Nie lepiej po prostu przekazać z GUI nazwę właściwości i kierunek sortowania? Da to znacznie większą elastyczność.

1 użytkowników online, w tym zalogowanych: 0, gości: 1