定义视图创建或数据库存储的选择/下拉选项的最佳实践方法是什么
本文关键字:选项 最佳 是什么 方法 创建 视图 数据库 选择 存储 定义 | 更新日期: 2023-09-27 18:27:50
我仍然不确定存储前端显示或数据库存储的选择列表选项的最佳方法。
我目前一直在使用枚举,并且还在使用描述装饰器(您如何从 MVC 中的枚举创建下拉列表 ASP.NET?
我现在在想,我不妨为这些东西创建一个完整的类,这样我就可以完全控制地正确存储以下信息:
- 项目名称
- 完整描述
- int 用于存储在数据库中
- 次序
- 从列表中获取信息的任何方法。
我应该考虑自己手动实现所有这些是对的吗?我想要一种非常可靠的方法来做到这一点,而枚举并不真正感觉它会削减它。
我应该考虑自己实施这一切是对的吗 手?
是的。枚举通常是泄漏和不充分的抽象,并不总是适合您实际希望表示的复杂领域模型。
与其自己动手,不如考虑 Headspring 的枚举类(通过 github、nuget(。我们一直使用它而不是枚举,因为它几乎一样简单,而且更加灵活。
"State"枚举并将其用作选择列表的示例:
public class State : Enumeration<State>
{
public static State Alabama = new State(1, "AL", "Alabama");
public static State Alaska = new State(2, "AK", "Alaska");
// .. many more
public static State Wyoming = new State(3, "WY", "Wyoming");
public State(int value, string displayName, string description) : base(value, displayName)
{
Description = description;
}
public string Description { get; private set; }
}
public IEnumerable<SelectListItem> Creating_a_select_list(State selected)
{
return State.GetAll().Select(
x => new SelectListItem
{
Selected = x == selected,
Text = x.Description,
Value = x.Value.ToString()
});
}
我并不是想向你推销这个特定的实现,你当然可以手工编写你自己的代码(枚举类只有大约 100 行代码(。但我绝对认为你会从超越基本枚举中受益。鉴于您在问题中描述的场景,这是正确的方法。
这些信息的第一个地方是数据库......或任何"虚拟商店",例如为您的数据库提供接口的 Web 服务。事实上,如果有其他数据库使用这些值,它们必须在数据库中表示,否则您将遇到大麻烦。事实上,假设其中一个这样的值是一个字符串。如果您没有定义包含所有可能值+键的表,而只是将字符串写入其他表中......您将无法更改字符串的格式,因为它将"散布"到您的数据库......相反,如果您只是使用外部密钥来引用此类字符串...您可以轻松更改它们,因为字符串仅存储在数据库中的一个位置。枚举解决方案还存在无法添加或删除值的问题......因此,如果此类操作"在概念上"可能有意义,则不能使用枚举。当所有选项"在概念上跨越"所有可能性时,可以使用枚举,因此您确定永远不会添加/删除其他选项,例如在枚举的情况下(是、否、未知(。
也就是说,一旦您在数据库中有了选择,其余的就很容易了......您将拥有 DTO 实体或业务实体,其表示方式与所有其他数据库实体完全相同。
出于可视化目的,您可能具有此选项的 ViewModel 版本,其中可能只包含键和说明,以及控制器可以调用的"存储库方法"来获得所有选项的列表。
检索到后,控制器将它们放在整个页面中 视图视图模型...以及要在页面上显示的所有其他信息。从视图模型...您可以访问它们以将它们放在下拉列表中。
总结:1( 您需要您的选项的数据库表示形式2(然后您将拥有此实体的DTO,业务层和视图版本...根据需要,与所有其他数据库实体完全相同。
您是否正在为所有选择列表选项寻找一刀切的解决方案?我个人主张选择最适合特定问题的选项。
在最近的一个项目中,我被介绍给Smart Enum的混合体。这是一个例子(我为错别字道歉,我打这个冷(:
public class Priority
{
public enum Types
{
High,
Medium,
Low
}
public Types Type { get; private set; }
public string Name { get { return this.Type.ToString(); } } // ToString() with no arguments is not deprecated
public string Description { get; private set; }
public static High = new Priority{ Type = Types.High, Description = "..."};
public static Medium = new Priority{ Type = Types.Medium, Description = "..."};
public static Low = new Priority{ Type = Types.Low, Description = "..."};
public static IEnumerable<Priority> All = new[]{High, Medium, Low};
public static Priority For(Types priorityType)
{
return All.Single(x => x.Type == priorityType);
}
}
因此,在实现中,您可以存储 Enum 值,但在呈现视图时,您将引用对象本身(Priority.For(entity.priority((以获取其他元数据。
这是否更接近您要查找的内容?
当然,其中一个问题是,如果您需要针对依赖于查找元数据的数据库编写查询,则此解决方案将在此过程中产生一些眼泪。
您可以使用"存储库模式"进行数据访问,并在控制器和视图之间使用视图模型。例:
//Model
public class CustomerViewModel
{
public Customer customer { get;set; }
public IEnumerable<Village> Villages { get; set; }
}
//Controller
public ActionResult Index()
{
var customerViewModel = new CustomerViewModel
{
Customer = new Customer(),
Villages = _villageService.GetAll()
};
return View(customerViewModel);
}
//View
@model ViewModel.RegisterViewModel
@Html.DropDownListFor(q => q.Customer.VillageId, new SelectList(Model.Villages, "Id", "Title"), "Please Select")
我写了一篇关于存储库模式的博客文章,你可以看看。
我将选项存储在视图模型本身中:
public class ViewModel {
[Required]
public int SelectListValue { get; set; }
public IDictionary<String,String> SelectListOptions {
get {
return new Dictionary<String, String>{
{ "0", Resources.Option1},
{ "1", Resources.Option2},
{ "2", Resources.Option3}
};
}
}
}
然后,我可以将以下行拖放到我的视图中以呈现选择列表:
<%= Html.DropDownListFor(m => m.SelectListValue, new SelectList(this.Model.SelectListOptions, "Key", "Value", "")) %>