我的数据库的字符串值受限于一组固定的值,如:
REGISTERED
PENDING
BANNED
目前我使用常量来表示这些值,但我宁愿使用enum
。
我使用的是EF 6,我认为它支持enum
,但是我可以使用枚举并将它作为字符串表示形式保存到数据库中吗?
public enum RegistrationStatus
{
REGISTERED,
BANNED,
PENDING
}
答案 0 :(得分:3)
我很抱歉这将是如此多的代码,但你可以创建一个基于字符串的类型安全枚举,并证明它工作的唯一方法是提供一个工作示例。
班级
public sealed class Frequency : IEnumeration, IComparable
我们在POCO中声明为
public Frequency chargeFrequency { get; set; }
在地图文件中就是这样 - 请注意我们映射到value
类的Frequency
属性
this.Property(t => t.chargeFrequency.Value)
.HasColumnName("chargeFrequency")
.HasColumnType("varchar")
.IsOptional()
.HasMaxLength(25);
这是一种享受。
x.chargeFrequency = Frequency.Annually
唯一的缺点是intellisense无法为我们解决这个问题。
班级的静态部分
private static readonly Dictionary<string, Frequency> _list =
new Dictionary<string, Frequency>();
public static bool Contains(string key)
{
return _list.Any(x => x.Key == key);
}
public static bool operator !=(Frequency a, Frequency b)
{
return (!a.Equals(b));
}
public static bool operator ==(Frequency a, Frequency b)
{
return (a.Equals(b));
}
public static implicit operator Frequency(string value)
{
if (value == null || value.Trim().Length == 0) return Frequency.Null;
if (Contains(value))
return _list[value];
else
throw new InvalidCastException(string.Format("Frequency.{0} not found.", value));
}
public static implicit operator String(Frequency item)
{
return item.Value;
}
public static readonly Frequency Null = new Frequency("");
public static readonly Frequency Annually = new Frequency("Annually");
public static readonly Frequency Fortnightly = new Frequency("Fortnightly");
public static readonly Frequency FourWeekly = new Frequency("FourWeekly");
public static readonly Frequency HalfYearly = new Frequency("HalfYearly");
public static readonly Frequency Monthly = new Frequency("Monthly");
public static readonly Frequency Quarterly = new Frequency("Quarterly");
班级的实例部分
private readonly string _value;
private readonly bool _readonly;
private Frequency _instance;
private Frequency(string value)
{
_readonly = true;
_value = value;
_instance = this;
_list[value] = _instance;
}
public Frequency()
{
_readonly = false;
_instance = Frequency.Null;
}
[XmlText]
public string Value
{
get
{
if (_instance == Frequency.Null) return null;
return _instance._value;
}
set
{
if (_readonly)
throw new InvalidOperationException("Cannot assign a value to an enumeration.");
if (value == null) _instance = Frequency.Null;
else
{
if (!_list.ContainsKey(value))
throw new NullReferenceException(string.Format("Frequency.{0} not found.", value));
_instance = _list[value];
}
}
}
public override string ToString()
{
return Value;
}
public override bool Equals(object obj)
{
if (obj == null) return false;
if (this.GetType() != obj.GetType()) return false;
// safe because of the GetType check
Frequency item = (Frequency)obj;
return System.Object.ReferenceEquals(_instance, item);
}
public override int GetHashCode()
{
if (_value == null) return "".GetHashCode();
else return _value.GetHashCode();
}
public int CompareTo(object obj)
{
if (obj is Frequency)
{
if (_value == null)
{
if (obj == null) return 0;
else return -1;
}
Frequency compare = (Frequency)obj;
return _instance.Value.CompareTo(compare.Value);
}
else
throw new ArgumentException("Object is not a Frequency.");
}
答案 1 :(得分:0)
根据您对我评论的回复,以下是我的回答:
EF完全支持使用enum
映射到自EF 5以来的数据库字段,但仅对int
值执行此操作。考虑到您的数据库使用字符串,我建议您进行一些“间接映射”。我的意思是在您的对象(该枚举类型)上有一个NotMapped
字段,当枚举更改时,该字段将使用字符串填充实际数据库字段。像这样:
public string RegistrationStatus { get; set; }
[NotMapped]
public RegistrationStatus EnumStatus
{
get { return (RegistrationStatus) Enum.Parse(typeof(RegistrationStatus), this.RegistrationStatus); }
set { this.RegistrationStatus = value.ToString();
}
通过执行此操作,您仍然可以将页面上的属性映射到此字段,并知道在更改时它将相应地更改基础string
值。