2016-11-10 3 views
1

Ich habe eine Reihe von Repositories in meiner App, und ich möchte versuchen, ein generisches Repository zu machen, um Code-Duplizierung zu reduzieren.Wie Lambda-Werte an ein generisches Repository übergeben werden

Eine Anforderung, die wiederholt auftritt, ist die Notwendigkeit, meine Entitäten in einer Dropdown-Liste aufzulisten.

In meinem aktuellen konkreten Repository Ich habe dies:

public IEnumerable GetSelectList() 
{ 
    return _context.Cultures.Select(x => new SelectListItem 
    { 
     Text = x.CultureKey, 
     Value = x.CultureID.ToString() 
    }).ToList(); 
} 

was So würde ich eine generische GetSelectList Funktion zu tun ist, die ich angeben lassen, welche Werte ich für die Text und Value Felder verwenden wollte in Mein Auswahllistenelement (im obigen Code sind dies CultureKey und CultureID).

Ich bin nicht sicher, wie ich diese Werte in einem generischen Repository konfigurierbar machen würde. Gibt es eine Möglichkeit, String-Werte als Lambda-Werte auszuwerten? Oder gibt es einen anderen Weg, um zu erreichen, was ich will?

+1

SelectListItem ist "View" verwandt und es wird Ihnen in Zukunft Probleme bereiten, wenn Sie View Logic mit Domain-Logik mischen. Alternativ können Sie ein Ansichtshilfsprogramm oder ein Ansichtsmodell hinzufügen, das bestimmte Felder in Schlüssel und Werte konvertiert. – axlj

Antwort

2

Puting beiseite die Frage, ob ein allgemeines Repository anythig über einen SelectListItem wissen sollte (protip: es sollte nicht) Sie können dies erreichen, indem

public class GenericRepo<T> 
{ 
    public IEnumerable GetSelectList(Func<T,string> text, Func<T,string> value) 
    { 
     return _context.Cultures.Select(x => new SelectListItem 
     { 
      Text = text(x), 
      Value = value(x) 
     }).ToList(); 
    } 
} 

in zwei Lamda Funktionen vorbei Sie haben eine intance von Unter der Annahme, GenericRepo<Culture> würden Sie tun dies

var selectList = repo.GetSelectList(x => x.CultureKey, x => x.CultureID.ToString()); 

ein wohl besserer Weg, dies zu entkoppeln könnte sein, so dass Ihre Methode gibt eine IEnumerable<Tuple<string,string>> und dass in Ihrem UI-Ebene auf eine SelectListItem abzubilden.

+0

Vervollständigen Sie den Punkt, dass dies nicht in das Repository gehört, weil es natürlich nicht. Annahme dieser Antwort, da sie die Lambda-Frage beantwortet –

0

Ich denke, Sie sollten Ihre Repositories von UI-Logik entkoppeln. Es ist nicht "richtig", UI-spezifische Logik wie SelectListItem auf Ihrer Datenzugriffsebene zu mischen.

Ich würde implementieren, welche Abfrage Sie für diese Methode benötigen und erstellen Sie die Liste der SelectListItem auf Controller.

OTOH Ich denke nicht, dass es sich lohnt, die Logik zu kapseln, um die Liste der SelectListItem zu erstellen, sobald Sie es auf den Controller verschieben, werden Sie nicht sehr viel gewinnen.

0

eine Erweiterungsmethode für IEnumerable<T> Erstellen einer Liste von SelectListItems zu konvertieren:

public static class Extensions 
{ 

    public static IEnumerable<SelectListItem> ToSelectList<T>(this IEnumerable<T> data, Func<T,string> text, Func<T,string> value) 
    { 
     return data.Select(x => new SelectListItem 
     { 
      Text = text(x), 
      Value = value(x) 
     }); 
    } 
} 

nun alles, was Sie brauchen, ist .ToSelectList() auf Ihre Sammlungen zu tun rufen jedes Element zu einem Element der Auswahlliste zu konvertieren. Dies ist hilfreich, weil Sie die Werte, die Sie für die Schlüssel/Werte in Ihren Repository-Klassen verwenden, nicht ausblenden.

var results = _cultures.ToSelectList(o=>o.CultureKey, o=>o.CultureId.ToString()); 
Verwandte Themen