LinqToDB可以将Enum属性的值存储为Enum的字符串值而不是整数值吗?
public enum OrderType
{
New,
Cancel
}
[Table("Orders")]
public class Order
{
[PrimaryKey, Identity]
public int OrderId { get; set; }
[Column]
public OrderType Type { get; set; }
}
如何让LinqToDB将“新建”或“取消”存储到数据库而不是0或1?
更新:似乎LinqToDB的答案是在枚举上设置MapValue属性。我一直试图找到在数据对象上指定它的位置。
public enum OrderType
{
[LinqToDB.Mapping.MapValue(Value = "NEW")]
New,
[LinqToDB.Mapping.MapValue(Value = "CANCEL")]
Cancel
}
这会将enum上的指定值存储为数据库中的文本。
答案 0 :(得分:6)
似乎LinqToDB的答案是在枚举上设置MapValue属性。我一直试图找到在数据对象上指定它的位置。
public enum OrderType
{
[LinqToDB.Mapping.MapValue(Value = "NEW")]
New,
[LinqToDB.Mapping.MapValue(Value = "CANCEL")]
Cancel
}
答案 1 :(得分:3)
您可能已经考虑过使用包装器类型来促进与枚举的转换,但为了以防万一,这里也是如此。
包装器允许您无法在枚举上隐式转换
您可以实现一个包装器,它允许一些非常有用的隐式转换(您无法对枚举类型本身执行此操作)。您可以将Column类型作为包装类型,但在DB中它可以存储为字符串,因为它隐式转换为字符串类型,并作为字符串类型检索,但作为包装类型返回,同样是因为隐式转换。
可以在使用枚举的任何地方使用
此外,因为它具有隐式转换,所以您的包装器类型可以代表在代码中使用枚举类型的任何位置。
<强>演示强>
以下是这种包装类型的演示以及它实现的无缝转换:
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();
}
}
}
答案 2 :(得分:0)
为什么需要将这些值转换为字符串?您必须考虑数据库性能和大小来执行这些操作。如果你想要简单的方法,你可以使用这样的东西:
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属性。