如何保持与数据库中的表同步的C#枚举 [英] How to keep a C# Enum in sync with a table in database

查看:143
本文介绍了如何保持与数据库中的表同步的C#枚举的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个稍微简化的例子(我改变了它来隐藏实际的代码)。
我有一个数据库驱动的应用程序和一个单独开发的小工具,旨在与应用程序配合使用。有一个表定义枚举,但它可能随着时间的推移而发生变化。假设一些应用程序(医疗?)需要跟踪一个人的性别。

This is a somewhat simplified example (I changed it around to hide the actual code). I have a database-powered app and a small tool that is being developed separately that is meant to work with the app. There is a table that defines an enumeration, but it could potentially change over time. Suppose some app (medical?) needed to track the sex of a person rather precisely.

select * from sex order by id;

id | mnemonic | description
0  | U        | Unknown sex
1  | M        | Male
2  | F        | Female
3  | T        | Trans-gender

而我的 C#枚举

public enum SexType
{
    /// <summary>Unknown sex.</summary>
    [Description("U")]
    Unknown = 0,

    /// <summary>Male sex.</summary>
    [Description("M")]
    Male = 1,

    /// <summary>Female sex.</summary>
    [Description("F")]
    Female = 2

    /// <summary>Trans-gender sex.</summary>
    [Description("T")]
    TransGender = 3,
}


$ b $这里我不应该假设id是连续的序列;即使可能看起来这些枚举标志也是可以组合的。

Here I should not assume that the id is a continuous sequence; neither are these enums flags that can be combined, even though it might look that way.

某些逻辑在SQL中完成;一些在 C#代码中完成。例如,我可能有一个函数:

Some of the logic is done in SQL; some is done in C# code. For instance, I might have a function:

// Here we get id for some record from the database.
public static void IsMaleOrFemale(int sexId)
{
    if (!Enum.IsDefined(typeof(SexType), sexId))
    {
        string message = String.Format("There is no sex type with id {0}.", 
            sexId);
        throw new ArgumentException(message, "sexId");
    }

    var sexType = (SexType) sexId;
    return sexType == SexType.Male || sexType == SexType.Female;
}

只要表和枚举定义都不会更改,这可以工作得很好。但表可能。我不能依靠id列或助记符列维护它们的值。我认为最好的是有一个单元测试,确保该表与我的枚举定义同步。我正在尝试将值与id匹配,并将描述属性匹配到助记符列。

This can work fairly well as long as neither the table nor the enum definitions change. But the table might. I cannot rely on the id column or the mnemonic column maintaining their values. I think the best I can to is have a unit test which makes sure that the table is in sync with my definition of an enum. I am trying to match the value to id, and the description attribute to mnemonic column.

所以,如何获取所有对的列表(以编程方式,在$ (0,U),(1,M),(2,F),(3,T )通过查看枚举SexType

So, how to I get a list of all pairs (programmatically, in C#): (0, "U"), (1, "M"), (2, "F"), (3, "T") by looking at the enum SexType?

想法是紧密比较这个

The idea is to tightly compare this ordered list with select id, mnemonic from sex order by is asc;.

推荐答案

如果你刚刚命名了枚举值U,M,F和T,那将会更简单。如果你这样做,那么 Enum 类的静态方法可以做所有的工作您。

It would be easier if you just named the enum values U, M, F and T. If you did that, the Enum class's static methods do all the work for you.

除此之外,您需要使用一点反思来挖掘描述属性

Barring that, you need to use a bit of reflection to dig out the Description attributes

public IEnumerable<Tuple<string, int>> GetEnumValuePairs(Type enumType)
{
    if(!enumType.IsEnum)
    {
        throw new ArgumentException();
    }

    List<Tuple<string, int>> result = new List<Tuple<string, int>>();

    foreach (var value in Enum.GetValues(enumType))
    {
        string fieldName = Enum.GetName(enumType, value);

        FieldInfo fieldInfo = enumType.GetField(fieldName);
        var descAttribute = fieldInfo.GetCustomAttributes(false).Where(a => a is DescriptionAttribute).Cast<DescriptionAttribute>().FirstOrDefault();

        // ideally check if descAttribute is null here
        result.Add(Tuple.Create(descAttribute.Description, (int)value));
    }

    return result;
}

这篇关于如何保持与数据库中的表同步的C#枚举的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆