如何将 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
函数,让我指定我想为我的 [=] 中的 Text
和 Value
字段使用什么值26=] 列表项(在上面的代码中是 CultureKey
和 CultureID
)。
我不确定如何在通用存储库中配置这些值。有没有办法将字符串值评估为 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());
我的应用程序中有许多存储库,我想尝试创建一个通用存储库以减少代码重复。
一个反复出现的要求是需要在下拉列表中列出我的实体。
在我当前的具体存储库中,我有这个:
public IEnumerable GetSelectList()
{
return _context.Cultures.Select(x => new SelectListItem
{
Text = x.CultureKey,
Value = x.CultureID.ToString()
}).ToList();
}
所以我想做的是有一个通用的 GetSelectList
函数,让我指定我想为我的 [=] 中的 Text
和 Value
字段使用什么值26=] 列表项(在上面的代码中是 CultureKey
和 CultureID
)。
我不确定如何在通用存储库中配置这些值。有没有办法将字符串值评估为 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 列表项目。这很有用,因为您没有隐藏您在存储库 类.
var results = _cultures.ToSelectList(o=>o.CultureKey, o=>o.CultureId.ToString());