我问了previous question关于使用LinqToSql在表上映射枚举值的问题,答案是使用O / R设计器将类型设置为global :: MyNamespace.TMyEnum。
如果您的枚举基于整数,则可以正常工作。但是如果你的枚举是基于字符串值怎么办?最明显的应用是:
public enum TGender {
Male,
Female,
Unknown,
}
数据库中的等效值为M
,F
和U
。您不能将枚举键入为字符串,那么如何使LinqToSql对象的Gender
属性返回TGender
值?
答案 0 :(得分:4)
我将为我的LINQ to SQL对象添加一个getter属性,如下所示:
public TGender Gender
{
switch(this.DbGender)
{
case "M":
return TGender.Male;
}
}
或者,如果您不想使用巨大的switch语句,则可以向枚举添加一个属性,该属性具有一个字符串属性,该属性表示数据库中该值的字符串值。然后,使用反射,获取正确的枚举,并返回。
以下是使用反射和属性执行此操作的示例:
public class EnumAttribute : Attribute
{
public string DbValue
{
get;
set;
}
}
public enum TGender
{
[EnumAttribute(DbValue = "M")]
Male,
[EnumAttribute(DbValue = "F")]
Female,
[EnumAttribute(DbValue = "U")]
Unknown
}
public TGender GetEnumValue(string s)
{
foreach (TGender item in Enum.GetValues(typeof(TGender)))
{
FieldInfo info = typeof(TGender).GetField(item.ToString());
var attribs = info.GetCustomAttributes(typeof(EnumAttribute), false);
if (attribs.Length > 0)
{
EnumAttribute a = attribs[0] as EnumAttribute;
if (s == a.DbValue)
{
return item;
}
}
}
throw new ArgumentException("Invalid string value.");
}
测试一下:
var item = GetEnumValue("M");
Console.WriteLine(item);
这导致“男性”。
答案 1 :(得分:1)
请允许我建议使用行为类而不是枚举。您将完全消除switch语句,并能够逐项关联元数据和行为。
public class Gender
{
private static readonly Dictionary<string, Gender> _items = new Dictionary<string, Gender>();
public static readonly Gender Male = new Gender("M", "he", age => age >= 14);
public static readonly Gender Female = new Gender("F", "she", age => age >= 13);
public static readonly Gender Unknown = new Gender("U", "he/she", age => null);
public string DatabaseKey { get; private set; }
public string Pronoun { get; private set; }
public Func<int, bool?> CanGetMarriedInTexas { get; set; }
private Gender(string databaseKey, string pronoun, Func<int,bool?> canGetMarriedInTexas)
{
DatabaseKey = databaseKey;
Pronoun = pronoun;
CanGetMarriedInTexas = canGetMarriedInTexas;
_items.Add(databaseKey, this);
}
public static Gender GetForDatabaseKey(string databaseKey)
{
if (databaseKey == null)
{
return Unknown;
}
Gender gender;
if (!_items.TryGetValue(databaseKey, out gender))
{
return Unknown;
}
return gender;
}
public IEnumerable<Gender> All()
{
return _items.Values;
}
}
而不是使用开关来获取数据库密钥,您只需要它:
public void MapViewToPerson(IEditPersonInfoView view, Person person)
{
person.Gender = view.Gender.DatabaseKey;
// ...
}
您还可以通过向Gender对象询问所需信息来应用性别特定行为。例如,德克萨斯州的合法婚姻同意年龄是针对性别的。
public void MapPersonToView(IEditPersonInfoView view, Person person)
{
Gender gender = Gender.GetForDatabaseKey(person.Gender);
view.Gender = gender;
view.ShowMarriageSection = gender.CanGetMarriedInTexas(person.AgeInYears) ?? true;
// ...
}