LinqToDB 如何将枚举存储为字符串值?
LinqToDB how to store enum as string value?
LinqToDB 能否将枚举的值 属性 存储为枚举的字符串值而不是整数值?
public enum OrderType
{
New,
Cancel
}
[Table("Orders")]
public class Order
{
[PrimaryKey, Identity]
public int OrderId { get; set; }
[Column]
public OrderType Type { get; set; }
}
如何让 LinqToDB 将 "New" 或 "Cancel" 而不是 0 或 1 存储到数据库?
更新: LinqToDB 的答案似乎是在枚举上设置 MapValue 属性。我一直试图找到在数据对象上指定它的位置。
public enum OrderType
{
[LinqToDB.Mapping.MapValue(Value = "NEW")]
New,
[LinqToDB.Mapping.MapValue(Value = "CANCEL")]
Cancel
}
这会将枚举中的指定值作为文本存储在数据库中。
您可能已经考虑过使用包装器类型来促进与枚举之间的转换,但为了以防万一,还是这样做吧。
包装器允许您无法在枚举上定义的隐式转换
您可以实现一个允许一些非常有用的隐式转换的包装器(您不能对枚举类型本身执行此操作)。你可以将 Column 类型作为你的包装类型,但在数据库中它可以存储为字符串,因为它隐式转换为字符串类型,并作为字符串类型检索,但作为你的包装类型返回,同样是因为隐式转换。
用enum的地方都可以用
此外,因为它具有隐式转换,所以您的包装类型可以代表代码中使用枚举类型的任何地方。
演示
下面是此类包装器类型的演示,以及它无缝启用的炫酷转换:
using System;
namespace ConsoleApplication
{
public static class Program
{
public enum OrderType
{
typeA,
typeB
}
public class OrderTypeWrapper
{
private OrderType enumValue;
public static implicit operator OrderType(OrderTypeWrapper wrapper)
{
return wrapper.EnumValue;
}
public static implicit operator OrderTypeWrapper(OrderType ot)
{
var wrapper = new OrderTypeWrapper();
wrapper.EnumValue = ot;
return wrapper;
}
public static implicit operator OrderTypeWrapper(String orderTypeValue)
{
var wrapper = new OrderTypeWrapper();
wrapper.StringValue = orderTypeValue;
return wrapper;
}
public static implicit operator String(OrderTypeWrapper wrapper)
{
return wrapper.StringValue;
}
public static implicit operator OrderTypeWrapper(int intValue)
{
var wrapper = new OrderTypeWrapper();
wrapper.IntValue = intValue;
return wrapper;
}
public static implicit operator int(OrderTypeWrapper wrapper)
{
return wrapper.IntValue;
}
public int IntValue
{
get
{
return (int)enumValue;
}
set
{
enumValue = (OrderType)value;
}
}
public String StringValue
{
get
{
return Enum.GetName(typeof(OrderType), enumValue);
}
set
{
try
{
//Use TyeParse to do something other than throw exception in presence of bad string value.
//Perhaps set it to an "invalid" signifying value of the enum, instead.
enumValue = (OrderType)Enum.Parse(typeof(OrderType), value, true); //throws exception on bad value
}
catch (ArgumentException ae)
{
var message = String.Format("Attempt to make a bad string value of \"{0}\" into an OrderType. ", value);
throw new Exception(message, ae);
}
}
}
public OrderType EnumValue
{
get
{
return enumValue;
}
set
{
enumValue = value; ;
}
}
}
public class Order
{
public OrderType TypeOfOrder { get; set;}
public String StringValueOfAnOrderType { get; set; }
public override String ToString()
{
return String.Format("TypeOfOrder={0}; StringValueOfAnOrderType={1}",TypeOfOrder,StringValueOfAnOrderType);
}
}
public static void Main(string[] args)
{
Order order = new Order();
Order order2 = new Order();
Order order3 = new Order();
//straight through, not that useful but shows that wrapper can stand in
order.TypeOfOrder = (OrderTypeWrapper)OrderType.typeB;
//int to string name of the enum value
order.StringValueOfAnOrderType = (OrderTypeWrapper)1;
Console.WriteLine("order: " + order);
//string to enum value, shows that case insensitive works, see third parameter of Parse.Enum to control this.
order2.TypeOfOrder = (OrderTypeWrapper)"TYPEB";
//enum value to string name of the enum value
order2.StringValueOfAnOrderType = (OrderTypeWrapper)OrderType.typeB;
Console.WriteLine("order2: " + order2);
//Not that helpful as you could also cast via (OrderType), but is shows that ints work, too.
order3.TypeOfOrder = (OrderTypeWrapper)1;
//Will helpfully blow up if the string type is wrong.
try
{
order3.StringValueOfAnOrderType = (OrderTypeWrapper)"typeC";
}
catch(Exception ex)
{
Console.WriteLine("Exception encountered: " + ex.Message);
}
Console.WriteLine("order3: " + order3);
var key = Console.ReadKey();
}
}
}
为什么需要将这些值转换成字符串?你必须考虑你的数据库性能和大小来做这些事情。如果你想要简单的方法来做到这一点,你可以使用这样的东西:
public class Order
{
[PrimaryKey, Identity]
public int OrderId { get; set; }
[Column]
public OrderType Type { get; set; }
private string _DisplayType;
[NotMapped]
public string DisplayType
{
get
{
if (Type != null)
_DisplayType = Type.ToString();
else
_DisplayType = string.Empty;
return _DisplayType;
}
set
{
if (_DisplayType != value)
{
_DisplayType = value;
}
}
}
}
如果想在其他地方显示,可以绑定DisplayType。如果要更改数据库中的值,可以使用 Type 属性.
LinqToDB 的答案似乎是在枚举上设置 MapValue 属性。我一直试图找到在数据对象上指定它的位置。
public enum OrderType
{
[LinqToDB.Mapping.MapValue(Value = "NEW")]
New,
[LinqToDB.Mapping.MapValue(Value = "CANCEL")]
Cancel
}
LinqToDB 能否将枚举的值 属性 存储为枚举的字符串值而不是整数值?
public enum OrderType
{
New,
Cancel
}
[Table("Orders")]
public class Order
{
[PrimaryKey, Identity]
public int OrderId { get; set; }
[Column]
public OrderType Type { get; set; }
}
如何让 LinqToDB 将 "New" 或 "Cancel" 而不是 0 或 1 存储到数据库?
更新: LinqToDB 的答案似乎是在枚举上设置 MapValue 属性。我一直试图找到在数据对象上指定它的位置。
public enum OrderType
{
[LinqToDB.Mapping.MapValue(Value = "NEW")]
New,
[LinqToDB.Mapping.MapValue(Value = "CANCEL")]
Cancel
}
这会将枚举中的指定值作为文本存储在数据库中。
您可能已经考虑过使用包装器类型来促进与枚举之间的转换,但为了以防万一,还是这样做吧。
包装器允许您无法在枚举上定义的隐式转换
您可以实现一个允许一些非常有用的隐式转换的包装器(您不能对枚举类型本身执行此操作)。你可以将 Column 类型作为你的包装类型,但在数据库中它可以存储为字符串,因为它隐式转换为字符串类型,并作为字符串类型检索,但作为你的包装类型返回,同样是因为隐式转换。
用enum的地方都可以用
此外,因为它具有隐式转换,所以您的包装类型可以代表代码中使用枚举类型的任何地方。
演示
下面是此类包装器类型的演示,以及它无缝启用的炫酷转换:
using System;
namespace ConsoleApplication
{
public static class Program
{
public enum OrderType
{
typeA,
typeB
}
public class OrderTypeWrapper
{
private OrderType enumValue;
public static implicit operator OrderType(OrderTypeWrapper wrapper)
{
return wrapper.EnumValue;
}
public static implicit operator OrderTypeWrapper(OrderType ot)
{
var wrapper = new OrderTypeWrapper();
wrapper.EnumValue = ot;
return wrapper;
}
public static implicit operator OrderTypeWrapper(String orderTypeValue)
{
var wrapper = new OrderTypeWrapper();
wrapper.StringValue = orderTypeValue;
return wrapper;
}
public static implicit operator String(OrderTypeWrapper wrapper)
{
return wrapper.StringValue;
}
public static implicit operator OrderTypeWrapper(int intValue)
{
var wrapper = new OrderTypeWrapper();
wrapper.IntValue = intValue;
return wrapper;
}
public static implicit operator int(OrderTypeWrapper wrapper)
{
return wrapper.IntValue;
}
public int IntValue
{
get
{
return (int)enumValue;
}
set
{
enumValue = (OrderType)value;
}
}
public String StringValue
{
get
{
return Enum.GetName(typeof(OrderType), enumValue);
}
set
{
try
{
//Use TyeParse to do something other than throw exception in presence of bad string value.
//Perhaps set it to an "invalid" signifying value of the enum, instead.
enumValue = (OrderType)Enum.Parse(typeof(OrderType), value, true); //throws exception on bad value
}
catch (ArgumentException ae)
{
var message = String.Format("Attempt to make a bad string value of \"{0}\" into an OrderType. ", value);
throw new Exception(message, ae);
}
}
}
public OrderType EnumValue
{
get
{
return enumValue;
}
set
{
enumValue = value; ;
}
}
}
public class Order
{
public OrderType TypeOfOrder { get; set;}
public String StringValueOfAnOrderType { get; set; }
public override String ToString()
{
return String.Format("TypeOfOrder={0}; StringValueOfAnOrderType={1}",TypeOfOrder,StringValueOfAnOrderType);
}
}
public static void Main(string[] args)
{
Order order = new Order();
Order order2 = new Order();
Order order3 = new Order();
//straight through, not that useful but shows that wrapper can stand in
order.TypeOfOrder = (OrderTypeWrapper)OrderType.typeB;
//int to string name of the enum value
order.StringValueOfAnOrderType = (OrderTypeWrapper)1;
Console.WriteLine("order: " + order);
//string to enum value, shows that case insensitive works, see third parameter of Parse.Enum to control this.
order2.TypeOfOrder = (OrderTypeWrapper)"TYPEB";
//enum value to string name of the enum value
order2.StringValueOfAnOrderType = (OrderTypeWrapper)OrderType.typeB;
Console.WriteLine("order2: " + order2);
//Not that helpful as you could also cast via (OrderType), but is shows that ints work, too.
order3.TypeOfOrder = (OrderTypeWrapper)1;
//Will helpfully blow up if the string type is wrong.
try
{
order3.StringValueOfAnOrderType = (OrderTypeWrapper)"typeC";
}
catch(Exception ex)
{
Console.WriteLine("Exception encountered: " + ex.Message);
}
Console.WriteLine("order3: " + order3);
var key = Console.ReadKey();
}
}
}
为什么需要将这些值转换成字符串?你必须考虑你的数据库性能和大小来做这些事情。如果你想要简单的方法来做到这一点,你可以使用这样的东西:
public class Order
{
[PrimaryKey, Identity]
public int OrderId { get; set; }
[Column]
public OrderType Type { get; set; }
private string _DisplayType;
[NotMapped]
public string DisplayType
{
get
{
if (Type != null)
_DisplayType = Type.ToString();
else
_DisplayType = string.Empty;
return _DisplayType;
}
set
{
if (_DisplayType != value)
{
_DisplayType = value;
}
}
}
}
如果想在其他地方显示,可以绑定DisplayType。如果要更改数据库中的值,可以使用 Type 属性.
LinqToDB 的答案似乎是在枚举上设置 MapValue 属性。我一直试图找到在数据对象上指定它的位置。
public enum OrderType
{
[LinqToDB.Mapping.MapValue(Value = "NEW")]
New,
[LinqToDB.Mapping.MapValue(Value = "CANCEL")]
Cancel
}