如何将 Lambda 值传递到通用存储库

How to pass Lambda values to a generic repository

我的应用程序中有许多存储库,我想尝试创建一个通用存储库以减少代码重复。

一个反复出现的要求是需要在下拉列表中列出我的实体。

在我当前的具体存储库中,我有这个:

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

所以我想做的是有一个通用的 GetSelectList 函数,让我指定我想为我的 [=] 中的 TextValue 字段使用什么值26=] 列表项(在上面的代码中是 CultureKeyCultureID)。

我不确定如何在通用存储库中配置这些值。有没有办法将字符串值评估为 lambda 值?还是有其他方法可以实现我想要的?

我认为您应该将存储库与 UI 逻辑分离。在您的数据访问层上将 UI 特定逻辑混合为 SelectListItem 并不是 "correct"。

我会在该方法上实现您需要的任何查询,并在控制器上构建 SelectListItem 的列表。

OTOH 我认为封装逻辑以创建 SelectListItem 的列表是不值得的,一旦将其移至控制器,您将不会获得太多收益。

抛开通用存储库是否应该知道任何关于 SelectListItem 的问题(提示:它不应该)你可以通过传递两个 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());

一个可以说更好的方法可能是将其解耦,因此您的方法 returns 一个 IEnumerable<Tuple<string,string>> 并将其映射到 UI 层中的 SelectListItem

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

现在,您只需在 collections 上调用 .ToSelectList() 即可将每个项目转换为 select 列表项目。这很有用,因为您没有隐藏您在存储库 类.

深处用于 keys/values 的值
var results = _cultures.ToSelectList(o=>o.CultureKey, o=>o.CultureId.ToString());