2013-12-16 12 views
9

は、私が現在働いているデータベースは、varchar型のフィールドを持っており、私のコードで私のような列挙にポテンシャル値をマップする:この列のデータベースレベルで列挙型のToStringの値を保証することは可能ですか?

public enum UserStatus 
{ 
    Anonymous, 
    Enrolled, 
    SuperUser 
} 

、上の制約があります値がなければならないこと:

UserStatus.SuperUser.ToString() 

そして、その値は、スーパーユーザーである必要があり、これが構成され:

ANONYMOUS 
ENROLLED 
SUPERUSER 

は、それが可能に私が行うためです蟻を縛って道を壊してはいけませんか?

+1

コードベースを管理している場合は、確実にそのコードベースを確認することができます。 –

+1

['ToUpperInvariant()'](http://msdn.microsoft.com/en-us/library/system.string.toupperinvariant(v = vs.110).aspx)? – PoByBolek

+1

これは必要ないかもしれません。あなたはSQL方言を指定しませんが、それらの多くはテキストのために大文字小文字を区別しません。これは '' SuperUser''が制約を満たすことを意味します。 – hvd

答えて

6

あなたが好き独自のExtension Methodを作成することができます代わりに、列挙型のためToStringをオーバーライドすることはできません。

public static class MyExtensions 
{ 
    public static string ToUpperString(this UserStatus userStatus) 
    { 
     return userStatus.ToString().ToUpper();// OR .ToUpperInvariant 
    } 
} 

そして好きそれを呼び出す:

string str = UserStatus.Anonymous.ToUpperString(); 
+0

ToUpperInvariant()は機能しませんか? – loyalflow

+0

@ user1361315、大文字と小文字を区別しない変換です。 [this](http://msdn.microsoft.com/en-us/library/system.string.toupperinvariant(v = vs.110).aspx)を参照してください。 – Habib

+0

私は文化を気にしません。データベースは文化によって変わるべきではありません。したがって、ToUpperInvariantを使用しますか? – loyalflow

7

よりよい解決策は、利点を活用することであってもよいですDescriptionAttribute

public enum UserStatus 
{ 
    [Description("ANONYMOUS")] 
    Anonymous, 
    [Description("ENROLLED")] 
    Enrolled, 
    [Description("SUPERUSER")] 
    SuperUser 
} 

以下のようなもの:

/// <summary> 
/// Class EnumExtenions 
/// </summary> 
public static class EnumExtenions 
{ 
    /// <summary> 
    /// Gets the description. 
    /// </summary> 
    /// <param name="e">The e.</param> 
    /// <returns>String.</returns> 
    public static String GetDescription(this Enum e) 
    { 
     String enumAsString = e.ToString(); 
     Type type = e.GetType(); 
     MemberInfo[] members = type.GetMember(enumAsString); 
     if (members != null && members.Length > 0) 
     { 
      Object[] attributes = members[0].GetCustomAttributes(typeof(DescriptionAttribute), false); 
      if (attributes != null && attributes.Length > 0) 
      { 
       enumAsString = ((DescriptionAttribute)attributes[0]).Description; 
      } 
     } 
     return enumAsString; 
    } 

    /// <summary> 
    /// Gets an enum from its description. 
    /// </summary> 
    /// <typeparam name="TEnum">The type of the T enum.</typeparam> 
    /// <param name="description">The description.</param> 
    /// <returns>Matching enum value.</returns> 
    /// <exception cref="System.InvalidOperationException"></exception> 
    public static TEnum GetFromDescription<TEnum>(String description) 
     where TEnum : struct, IConvertible // http://stackoverflow.com/a/79903/298053 
    { 
     if (!typeof(TEnum).IsEnum) 
     { 
      throw new InvalidOperationException(); 
     } 
     foreach (FieldInfo field in typeof(TEnum).GetFields()) 
     { 
      DescriptionAttribute attribute = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute)) as DescriptionAttribute; 
      if (attribute != null) 
      { 
       if (attribute.Description == description) 
       { 
        return (TEnum)field.GetValue(null); 
       } 
      } 
      else 
      { 
       if (field.Name == description) 
       { 
        return (TEnum)field.GetValue(null); 
       } 
      } 
     } 
     return default(TEnum); 
    } 
} 

だから今、あなたはUserStatus.Anonymous.GetDescription()を参照しています。

もちろん、自分でDatabaseMapAttribute(またはwhat-have-you)を作成して独自の拡張メソッドを作成することもできます。その後、System.ComponentModelへの参照を削除することができます。あなたの呼び出しを完全に。

+0

'GetDescription()'と定義した場合、 'ToDescription()'ではなく、 'GetDescription()'としても呼び出す必要があります。 – hvd

+0

@hvd:良い呼び出しです。月曜日もまだ通り過ぎています。 ;-) –

+2

これは本当に良いですか?あなたが維持しなければならないコードの量から判断すると、私はHabibのソリューションを好むでしょう。 – PoByBolek

1

Enum.ToStringは4 different formatsをサポートします。私は行きます:

UserStatus.SuperUser.ToString("G").ToUpper(); 

"G"は、まず列挙の文字列表現を取得しようとします。

関連する問題