我的应用程序中有许多存储库,我想尝试创建一个通用存储库来减少代码重复。
反复出现的一个要求是需要在下拉列表中列出我的实体。
在我目前的具体存储库中,我有这个:
public IEnumerable GetSelectList()
{
return _context.Cultures.Select(x => new SelectListItem
{
Text = x.CultureKey,
Value = x.CultureID.ToString()
}).ToList();
}
所以我想要做的是拥有一个通用的GetSelectList
函数,让我可以为我的选择列表项中的Text
和Value
字段指定我想要使用的值(在上面的代码中,CultureKey
和CultureID
)。
我不确定如何在通用存储库中配置这些值。有没有办法将字符串值计算为lambda值?或者是否有其他方法可以实现我想要的目标?
答案 0 :(得分:2)
抛开一个通用存储库是否应该知道关于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>>
并将其映射到您的UI图层中的SelectListItem
。
答案 1 :(得分:0)
我认为您应该将您的存储库与UI逻辑分离。在您的数据访问层上将UI特定逻辑混合为SelectListItem
并不“正确”。
我将在该方法上实现您需要的任何查询,并在控制器上构建SelectListItem
列表。
OTOH我认为将SelectListItem
列表移动到控制器后创建{{1}}列表的逻辑是不值得的,你不会获得太多收益。
答案 2 :(得分: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());