我正在將此作爲一個社區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