对云中的asp.net MVC应用程序使用枚举或数据库查找表或两者的最佳实践/设计决策是什么?

mas*_*700 6 asp.net-mvc asp.net-mvc-4

我正在编写一个Asp.net MVC应用程序,但我不确定是否有设计决定.我不确定最好的设计是使用枚举值还是将这些值存储为数据库中的查找表.我可以想象查找表适用于Windows应用程序,其中所有这些查询都不是问题,但对于在云中运行的高流量Web应用程序,使用关系数据库我不太确定.

应用程序需要可维护,并且将来需要支持多语言.其他开发人员将不得不在系统上工作,因此我需要设计正确且易于维护.

我目前使用枚举值来表示NotificationMethod(无,电子邮件,短信),
性别(男性,女性)OrderStatus(Open,Closed,InProgres,DeliveryInProgress PaymentService(Cash,BankTransfer,Paypal,GoogleWallet))

枚举适合我,因为链接到枚举的代码中有业务规则,并且具有枚举值而不是字符串的业务规则使应用程序更具可读性并且更不容易出错.

但是,上述情况不适合以下情况.我的网络前端有一个选择/下拉控件.要填充下拉列表,我有以下代码

  var paymentServices=
          Enum.GetValues(typeof(PaymentService))
          .Cast<PaymentService >()
          .Select(d => new SelectListItem()
          {
              Text = d.ToString(),
              Value = ((int)d).ToString()
          }).ToList();
Run Code Online (Sandbox Code Playgroud)

而不是枚举值电子邮件我想显示电子邮件,我想要在单词之间的空格.

所以我最终使用属性并在EnumHelper类中使用静态方法来读取这里描述的属性

我的订单和首选项数据库表我每个表中有大约20个这些枚举.

对于我的场景,最佳做法是

  1. 仅使用带有枚举属性的C#枚举来显示诸如FriendlyNames,Description,Tooltip等显示值.

  2. 只需使用数据库查找表.缺点是业务规则必须基于查找表中所选值的String值.要转到我的首选项或订购编辑屏幕,我必须在数据库中单独读取20个查找表,以便呈现下拉控件.这使得编写代码和报告变得更加容易,但系统将负载很重(系统有数千个用户)

  3. 为业务规则提供简单的枚举值,并使用匹配的查找数据库表,并在这些表中存储要在前端UI上显示的其他显示列.缺点是我必须使基本枚举编号与数据库查找表保持同步.

您如何决定最佳设计决策还是有更好的解决方案?

Gut*_*tsy 6

为业务规则提供简单的枚举值,并使用匹配的查找数据库表,并在这些表中存储要在前端UI上显示的其他显示列.缺点是我必须使基本枚举编号与数据库查找表保持同步.

您可以调查T4模板,这意味着应用程序中的枚举是半自动地从数据库中的查找表构建的.(您可以从构建菜单中选择一个选项来重新创建所有选项.)我们目前在一个大型项目中执行此操作并且运行良好.

当然,好处是您不必在应用程序中使用幻数或手动保持同步.外键和强类型代码,双赢.

这似乎是相关的:SQL表和C#枚举

为了扩展这一点,我们还使用反射来获取枚举的DisplayValue属性.但是,仅仅因为我们这样做并不是最佳实践.我们在客户端计算机上运行,​​而不是在云中运行,因此反射不是一个大问题.我不知道当你从一台机器上提供多个用户时,反射会有多大.也就是说,Microsoft在使用HTML Helpers时充分利用了反射,并且反射速度可能比使用数据库20次更快.但我离题了......


Mat*_*don 3

如果您的枚举值需要本地化,为什么不积极主动地立即使用 .resx 文件作为英文字幕呢?使用属性意味着您静态地声明每个枚举值的描述​​,这本质上与可本地化相反。

给定using resx = namespace.resxFile(我建议使用一个专门用于保存枚举值的标题的 .resx 文件 - 即我将其他 UI 资源放在另一个文件中)每个枚举值都存储为按约定命名的字符串[enumValue]Caption,您的paymentServices列表可能如下所示:

var paymentServices =
    Enum.GetValues(typeof(PaymentService))
        .Cast<PaymentService>()
        .Select(d => new SelectListItem()
        {
            Text = resx.ResourceManager
                       .GetString(string.Format("{0}Caption", d.ToString())),
            Value = ((int)d).ToString()
        }).ToList();
Run Code Online (Sandbox Code Playgroud)

当需要本地化时,您所需要做的就是翻译 .resx 文件并将资源的区域性设置为所需的区域性。

缺点显然是您无法拥有让用户编辑翻译并添加新支持的语言等功能,因为 .resx 文件内置于您的应用程序中;这也意味着每当需要新的枚举值时就需要更改代码。

好处是您不需要访问数据库,并且您的代码是独立的,这意味着未来的开发人员不需要在代码库之外的其他任何地方查找任何内容。

哪个最好归结为您的需求和要求。