2016-11-10 2 views
1

У меня есть несколько репозиториев в моем приложении, и я хочу попробовать создать общий репозиторий, чтобы сократить дублирование кода.Как передать значения Lambda в общий репозиторий

Одним из требований, которые возникают неоднократно, является необходимость перечисления моих объектов в выпадающем списке.

В моем текущем бетонном хранилище У меня есть это:

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

Так что я хотел бы сделать, это иметь общий GetSelectList функцию, которая позволит мне указать, какие значения я хотел использовать для Text и Value полей мой элемент списка избранного (в коде выше CultureKey и CultureID).

Я не уверен, как сделать эти значения настраиваемыми в общем репозитории. Есть ли способ оценить значения строк в виде значений лямбда? Или есть другой способ добиться того, чего я хочу?

+1

SelectListItem - это «Просмотр», связанный с этим, и это вызовет ваши боли в будущем, если вы начнете смешивать логику вида с логикой домена. В качестве альтернативы добавьте вспомогательную или обзорную модель представления, которая преобразует определенные поля в ключи и значения. – axlj

ответ

2

Puting в стороне вопрос о том, должен ли общий репозиторий знать о ничего делать дополнительно SelectListItem (protip: она не должна), вы можете достичь этого путем передачи двух функций LAMDA

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(); 
    } 
} 

Предполагая, что у вас есть из входом в инстанс GenericRepo<Culture> вы могли бы сделать это

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

, возможно, лучший способ может быть разъединить это, так что ваш метод возвращает IEnumerable<Tuple<string,string>> и карту, что к SelectListItem в вашем слое UI.

+0

Полностью признайте, что это не относится к репозиторию, потому что, конечно, это не так. принимая этот ответ, поскольку он отвечает на вопрос лямбда –

0

Я думаю, вы должны отделить свои репозитории от логики пользовательского интерфейса. Неправильно смешивать специфическую логику UI как SelectListItem на вашем уровне доступа к данным.

Я бы выполнил любой запрос, который вам нужен, и построил список SelectListItem на контроллере.

OTOH Я не думаю, что стоит потратить усилия на инкапсуляцию логики для создания списка SelectListItem, как только вы переместите его на контроллер, вы не получите очень много.

0

Создать метод расширения для IEnumerable<T> преобразовать в список SelectListItems:

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) 
     }); 
    } 
} 

Теперь все, что вам нужно сделать, это позвонить .ToSelectList() на вашей коллекции, чтобы преобразовать каждый элемент выбора элемента списка. Это полезно, потому что вы не скрываете значения, которые вы используете для ключей/значений в глубине ваших классов репозитория.

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