6

如果我想将数据库中 spicelevel 列的值限制为 1、2 和 3,我可以执行类似的操作

    private enum SpiceLevel
    {
        Low=1,
        Medium=2,
        Hot=3
    }

然后在代码中我可以(int)SpiceLevel.Low选择 1 作为香料级别。

现在,如果我需要只能接受“红玫瑰”、“白玫瑰”和“黑玫瑰”作为数据库中列的值,该怎么办?什么是处理这个问题的优雅方式?

我正在考虑将它们存储在配置文件或常量中,但它们都不像枚举那样优雅。有任何想法吗?

更新:

这里的答案对我有用

4

4 回答 4

7

您可以property为此使用

public string[] AllowedRoses = new string[] {  "Red Rose", "White Rose" ,"Black Rose" };
string _Rose = "Red Rose";
public string Rose
{
    get
    {
        return _Rose;
    }
    set
    {
        if (!AllowedRoses.Any(x => x == value)) 
               throw new ArgumentException("Not valid rose");
        _Rose = value;
    }
}
于 2013-08-15T23:18:49.900 回答
1

我可以看到以下选项:

  • 验证设置器中的值(参见例如 l4V 的答案)

  • 从概念上讲,您正在考虑枚举。因此,您可以执行以下操作:

enum RoseType { RedRose, WhiteRose, BlackRose };

然后提供从这个枚举到字符串的适当转换。这里描述了两个方便的选项:Enum ToString with user friendly strings。一种是使用自定义 Description 属性,第二种(我更喜欢这个)提供扩展方法:

public static class RoseTypeExtensions
{
  public static string GetString(this RoseType @this)
  {
    switch (@this)
    {
      case RoseType.RedRose:
        return "Red Rose";
      case RoseType.WhiteRose:
        return "White Rose";
      case RoseType.BlackRose:
        return "Black Rose";
      default:
        throw new InvalidOperationException();
    }
  }
}
  • 创建一组常量:
public class RoseType
{
  public readonly RoseType RedRose = new RoseType("Red Rose");
  public readonly RoseType WhiteRose = new RoseType("White Rose");
  public readonly RoseType BlackRose = new RoseType("Black Rose");

  public string Content { get; private set; }

  private RoseType(string content)
  {
    this.Content = content;
  }

  public override string ToString()
  {
    return this.Content;
  }
}

正如 Oskar Berggren 在评论中正确指出的那样,除了: 、和. 之外,RoseType还应该提供其他标准覆盖。ToStringEqualsGetHashCodeoperator==operator!=

于 2013-08-15T23:23:52.780 回答
0

There is no really good solution. All of them require the database to be "synchronized" with the enum in C#.

Simplest solution:

What you said store the enum values as integers in the database.

Almost as simple but less efficient:

Store the values as strings in the database and convert between string and enum with anEnumVar.ToString() and Enum.Parse (or any of the other parse methods in Enum).

Complex but flexible:

Have a sort of enum in the database: a table with string values and ids and then use foreign keys to that table where you want to save the enums. This allows you to either select/update/insert using the numeric value or the string value (via a join).

It also maintains integrity as it is not possible to store an integer which has no corresponding enum value.

The downside is the complexity.

于 2013-08-15T23:22:24.430 回答
0

创建字符串到枚举的映射,以将字符串与枚举Dictionary<string, SpiceLevel>相关联。将它们包装在一个类中。

您还可以使用 Decorator 属性[Name("Red Rose"] Low=1,并从枚举本身获取该属性,但这涉及反射,这会产生一些性能问题,尤其是在遍历枚举值以查找具有匹配属性的值时。

public static class Spice
{
    public enum Level
    {
        Low = 1,
        Medium = 2,
        Hot = 3
    }

    private static readonly Dictionary<string, Level> spices = new Dictionary<string, Level>{
        { "Red Rose", Level.Low },
        { "White Rose", Level.Medium },
        { "Black Rose", Level.Hot },
    };

    public static bool TryGet(string spiceName, out Level spiceLevel) => spices.TryGetValue(spiceName, out spiceLevel);

    public static string SpiceName(Level target) => Enum.GetName(typeof(Spice.Level), target);
}

/// <summary>
/// Some tests to validate it works. This could be a unit test or just in a console app
/// </summary>
public class SpiceTest
{
    public void VerifyBlackRoseIsHot()
    {
        string subject = "Black Rose";
        Spice.Level expectedSpice;

        // Here's the ease of use. Pass a string, get an enum and whether it's a valid string
        var result = Spice.TryGet(subject, out expectedSpice);

        //Some Assertion from a unit test library
        Assert.True(result, $"Unable to find spice '{subject}', when it should exist");
        Assert.True(Spice.Level.Hot.Equals(expectedSpice), $"The returned spice '{ Spice.SpiceName(expectedSpice) }' was not the value 'Hot' as expected");
    }
}
于 2019-01-22T21:56:50.453 回答