如何保持与数据库中的表同步的C#枚举 [英] How to keep a C# Enum in sync with a table in database
问题描述
这是一个稍微简化的例子(我改变了它来隐藏实际的代码)。
我有一个数据库驱动的应用程序和一个单独开发的小工具,旨在与应用程序配合使用。有一个表定义枚举,但它可能随着时间的推移而发生变化。假设一些应用程序(医疗?)需要跟踪一个人的性别。
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屋!