2009-12-28 107 views
6

我正在將此作爲一個社區wiki,因爲我會欣賞人們的做法,而不一定是答案。枚舉或表?

我在這種情況下,我有很多查找類型數據字段,不會改變。一個例子是:

年薪
選項:0 - 25K
選項:25K - 100K
選項:100K +

我想有容易獲得這些選項通過枚舉,但也想在數據庫中提供文本值,因爲我會報告文本值而不是ID。另外,由於它們是靜態的,我不想調用數據庫。

我想在一個枚舉和表中複製這個,但想聽到一些替代想法。

謝謝

回答

7

我認爲枚舉是一個壞主意。只要給出你顯示的數據類型,它可能會改變。最好是在應用程序初始化時加載具有ID/Min/Max/Description字段的數據庫表。

+0

這是一個例子來創建枚舉,它也不會改變。無論如何,我喜歡你的方法,你會如何堅持整個應用程序的數據。是否有任何性能問題,99%的應用程序不需要數據? – 2009-12-28 17:49:18

+1

如果這些數據很少被訪問,那麼您可以將它保存在第一次請求數據時初始化的靜態類(延遲初始化)。只要確保鎖定在適當的位置,以便一次只有一個線程可以訪問該數據。這將消除任何啓動速度減慢。如果您不希望第一次訪問數據時等待,您還可以將數據加載到低優先級的工作隊列中,以便在閒置一兩次時加載(或者在需要時立即加載) – Eclipse 2009-12-28 17:56:56

+2

如果它確實不會改變,並且您沒有數據庫,那麼您可以將其存儲在自定義節中的app.config文件中。 – 2009-12-28 21:45:05

1

我同時使用。在Linq to SQL和EF中,只需將列屬性設置爲枚舉類型即可。在其他框架中,您通常可以以某種方式將列映射到枚舉屬性。您仍然可以在包含有效枚舉的數據庫中使用主鍵表。

您也可以在數據庫中使用CHECK約束來做到這一點,但這往往會將數據綁定到應用程序 - 單獨查看數據庫的人不一定會知道每個值的含義。因此我更喜歡混合表/枚舉。

0

首先確保這些數據真的是靜態的。如果有任何更改,您將不得不重新編譯和重新部署。

如果數據真的是靜態的,我會去enum路由。您可以創建一個YearlySalaryEnum保存所有值。對於字符串表示,我將使用帶有字符串值的字典和作爲密鑰的YearlySalaryEnum。字典可以保存爲靜態類中的靜態實例。用法是沿(C#)線:

string highSalary = StaticValues.Salaries[YearlySalaryEnum.High]; 
+0

SQL報告怎麼樣?如何使用僅枚舉方法解決這個問題。 – 2009-12-28 17:46:22

+1

從DB初始化字典,很簡單。如果枚舉後面的數據類型是整數,則將其映射到數據庫列很簡單。正如Aaron指出的那樣,許多ORM可以開箱即用。 – 2009-12-28 17:49:09

-1

使用枚舉(代碼)和DB texts-的GUI表示。

所以,如果你將永遠有3選項,在DB使用枚舉LowSalaryMiddleSalaryHighSalary,存儲您的文本和對應於你的財產枚舉值的GUI切換您的文本。

1

同時使用,你應該調查CodeDOM。使用它你可以編寫代碼生成例程,通過讀取數據庫,編譯過程可以自動生成一個程序集或類,並在其中包含這些枚舉。這樣您就可以讓數據庫驅動器,但是每次訪問枚舉實例時都不會調用數據庫...

0

因爲C#不允許使用帶有字符串值的枚舉,所以我會建議結構與一些靜態字符串。

通過這種方式,您可以維護一些智能感知,但不會試圖在數據庫中的字符串值上使用Enum值。

我會提供的另一種解決方案:取消依賴這些值的邏輯並轉移到基於表的邏輯。 (例如,如果每筆交易的稅率不同,請將稅率作爲數據庫中的列添加,而不是代碼中的案例{})。

2

一種方法是編寫一個格式,可以把你枚舉成字符串表示:

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)); 

格式化可以推廣的,以支持通過格式化字符串,多種類型,本地化等不同的格式。

+0

我認爲他們不會理解這個想法。我不知道爲什麼,但有一個數據庫表爲這3個變量可以看到他們更好...... – serhio 2009-12-29 09:47:36

1

看一看我的建議在這裏How to work with Enums in Entity Framework?

基本上我使用默認值核心查找數據的SQL腳本,用的ID從其他表FK參考,然後我用一個簡單的T4模板來生成我枚舉了C#。這樣數據庫就是高效的,規範化的並且正確地受到限制,而且我的c#實體不必處理ID(幻數)。

它簡單快速,簡單,併爲我做的工作。

我使用EF4,但你不需要,可以使用這種方法與任何你用於實體的技術。

6

對於靜態項目,我使用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."); 
}