LinqToDB如何将枚举存储为字符串值?

时间:2015-04-14 02:36:51

标签: c# string enums linq2db

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上的指定值存储为数据库中的文本。

3 个答案:

答案 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属性。