我正在将此作为一个社区wiki,因为我会欣赏人们的做法,而不一定是答案。枚举或表?
我在这种情况下,我有很多查找类型数据字段,不会改变。一个例子是:
年薪
选项:0 - 25K
选项:25K - 100K
选项:100K +
我想有容易获得这些选项通过枚举,但也想在数据库中提供文本值,因为我会报告文本值而不是ID。另外,由于它们是静态的,我不想调用数据库。
我想在一个枚举和表中复制这个,但想听到一些替代想法。
谢谢
我正在将此作为一个社区wiki,因为我会欣赏人们的做法,而不一定是答案。枚举或表?
我在这种情况下,我有很多查找类型数据字段,不会改变。一个例子是:
年薪
选项:0 - 25K
选项:25K - 100K
选项:100K +
我想有容易获得这些选项通过枚举,但也想在数据库中提供文本值,因为我会报告文本值而不是ID。另外,由于它们是静态的,我不想调用数据库。
我想在一个枚举和表中复制这个,但想听到一些替代想法。
谢谢
我认为枚举是一个坏主意。只要给出你显示的数据类型,它可能会改变。最好是在应用程序初始化时加载具有ID/Min/Max/Description字段的数据库表。
我同时使用。在Linq to SQL和EF中,只需将列属性设置为枚举类型即可。在其他框架中,您通常可以以某种方式将列映射到枚举属性。您仍然可以在包含有效枚举的数据库中使用主键表。
您也可以在数据库中使用CHECK约束来做到这一点,但这往往会将数据绑定到应用程序 - 单独查看数据库的人不一定会知道每个值的含义。因此我更喜欢混合表/枚举。
首先确保这些数据真的是静态的。如果有任何更改,您将不得不重新编译和重新部署。
如果数据真的是静态的,我会去enum路由。您可以创建一个YearlySalaryEnum
保存所有值。对于字符串表示,我将使用带有字符串值的字典和作为密钥的YearlySalaryEnum
。字典可以保存为静态类中的静态实例。用法是沿(C#)线:
string highSalary = StaticValues.Salaries[YearlySalaryEnum.High];
SQL报告怎么样?如何使用仅枚举方法解决这个问题。 – 2009-12-28 17:46:22
从DB初始化字典,很简单。如果枚举后面的数据类型是整数,则将其映射到数据库列很简单。正如Aaron指出的那样,许多ORM可以开箱即用。 – 2009-12-28 17:49:09
使用都枚举(代码)和DB texts-的GUI表示。
所以,如果你将永远有3选项,在DB使用枚举LowSalary
,MiddleSalary
和HighSalary
,存储您的文本和对应于你的财产枚举值的GUI切换您的文本。
同时使用,你应该调查CodeDOM。使用它你可以编写代码生成例程,通过读取数据库,编译过程可以自动生成一个程序集或类,并在其中包含这些枚举。这样您就可以让数据库驱动器,但是每次访问枚举实例时都不会调用数据库...
因为C#不允许使用带有字符串值的枚举,所以我会建议结构与一些静态字符串。
通过这种方式,您可以维护一些智能感知,但不会试图在数据库中的字符串值上使用Enum值。
我会提供的另一种解决方案:取消依赖这些值的逻辑并转移到基于表的逻辑。 (例如,如果每笔交易的税率不同,请将税率作为数据库中的列添加,而不是代码中的案例{})。
一种方法是编写一个格式,可以把你枚举成字符串表示:
public class SalaryFormatter : IFormatProvider, ICustomFormatter
{
public object GetFormat(Type formatType)
{
return (formatType == typeof(ICustomFormatter)) ? new
SalaryFormatter() : null;
}
public string Format(string format, object o, IFormatProvider formatProvider)
{
if (o.GetType().Equals(typeof(Salary)))
{
return o.ToString();
Salary salary = (Salary)o;
switch (salary)
{
case Salary.Low:
return "0 - 25K";
case Salary.Mid:
return "25K - 100K";
case Salary.High:
return "100K+";
default:
return salary.ToString();
}
}
return o.ToString();
}
}
你使用像任何其他格式格式化:
Console.WriteLine(String.Format(new SalaryFormatter(), "Salary: {0}", salary));
格式化可以推广的,以支持通过格式化字符串,多种类型,本地化等不同的格式。
我认为他们不会理解这个想法。我不知道为什么,但有一个数据库表为这3个变量可以看到他们更好...... – serhio 2009-12-29 09:47:36
看一看我的建议在这里How to work with Enums in Entity Framework?
基本上我使用默认值核心查找数据的SQL脚本,用的ID从其他表FK参考,然后我用一个简单的T4模板来生成我枚举了C#。这样数据库就是高效的,规范化的并且正确地受到限制,而且我的c#实体不必处理ID(幻数)。
它简单快速,简单,并为我做的工作。
我使用EF4,但你不需要,可以使用这种方法与任何你用于实体的技术。
对于静态项目,我使用Enum和每个元素的[Description()]属性。 和T4模板再生枚举与构建描述(或者只要你想)
public enum EnumSalary
{
[Description("0 - 25K")] Low,
[Description("25K - 100K")] Mid,
[Description("100K+")] High
}
而且使用它像
string str = EnumSalary.Mid.Description()
附:还创建扩展System.Enum
public static string Description(this Enum value) {
FieldInfo fi = value.GetType().GetField(value.ToString());
var attributes = (DescriptionAttribute[]) fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
return attributes.Length > 0 ? attributes[0].Description : value.ToString();
}
和反向通过描述
public static TEnum ToDescriptionEnum<TEnum>(this string description)
{
Type enumType = typeof(TEnum);
foreach (string name in Enum.GetNames(enumType))
{
var enValue = Enum.Parse(enumType, name);
if (Description((Enum)enValue).Equals(description)) {
return (TEnum) enValue;
}
}
throw new TargetException("The string is not a description or value of the specified enum.");
}
这是一个例子来创建枚举,它也不会改变。无论如何,我喜欢你的方法,你会如何坚持整个应用程序的数据。是否有任何性能问题,99%的应用程序不需要数据? – 2009-12-28 17:49:18
如果这些数据很少被访问,那么您可以将它保存在第一次请求数据时初始化的静态类(延迟初始化)。只要确保锁定在适当的位置,以便一次只有一个线程可以访问该数据。这将消除任何启动速度减慢。如果您不希望第一次访问数据时等待,您还可以将数据加载到低优先级的工作队列中,以便在闲置一两次时加载(或者在需要时立即加载) – Eclipse 2009-12-28 17:56:56
如果它确实不会改变,并且您没有数据库,那么您可以将其存储在自定义节中的app.config文件中。 – 2009-12-28 21:45:05