我正在尝试使用Dapper
和Dapper-Extensions
并将数据库上的enums
序列化为string
。
现在,它们被序列化为整数(在VARCHAR
字段内)。
有没有办法做到这一点?我可以添加的任何自定义类型映射?
如果我不能通过它,我可能需要回到EF ..
感谢Marc Gravell回复:
唯一的方法是手动执行插入。
还使用以下帖子: 如何使用Dapper执行插入并返回插入的标识?
低于我的解决方案
请注意,选择自动工作:您可以直接使用Dapper(Extensions) GetList<T>
,没有映射到需要的枚举。
public enum ComponentType
{
First,
Second,
Third
}
public class Info
{
public int Id { get; set; }
public ComponentType InfoComponentType { get; set; }
public static void SaveList(List<Info> infoList)
{
string ConnectionString = GetConnectionString();
using (SqlConnection conn = new SqlConnection(ConnectionString))
{
conn.Open();
foreach (Info info in infoList)
{
string sql = @"INSERT INTO [Info] ([InfoComponentType])
VALUES (@InfoComponentType);
SELECT CAST(SCOPE_IDENTITY() AS INT)";
int id = conn.Query<int>(sql, new
{
InfoComponentType = info.InfoComponentType.ToString()
}).Single();
info.Id = id;
}
conn.Close();
}
}
}
有一种方法,我认为它更健壮,更干净。
我提供的解决方案适用于任何枚举,但它涉及一些额外的编码。它还涉及在Dapper中添加自定义类型处理程序。但是,如果这个答案得到一些投票,我将更改Dapper源代码,以便在类型处理中自动包含此解决方案并请求拉取请求。
我实际上实现了这个解决方案并在生产中使用它。
开始。
首先是struct(不是类,因为struct只包含一个字符串引用),它将用作枚举:
public struct Country
{
string value;
public static Country BE => "BE";
public static Country NL => "NL";
public static Country DE => "DE";
public static Country GB => "GB";
private Country(string value)
{
this.value = value;
}
public static implicit operator Country(string value)
{
return new Country(value);
}
public static implicit operator string(Country country)
{
return country.value;
}
}
现在我们需要一个这个结构的类型处理程序
public class CountryHandler : SqlMapper.ITypeHandler
{
public object Parse(Type destinationType, object value)
{
if (destinationType == typeof(Country))
return (Country)((string)value);
else return null;
}
public void SetValue(IDbDataParameter parameter, object value)
{
parameter.DbType = DbType.String;
parameter.Value = (string)((dynamic)value);
}
}
在应用程序启动的某个地方,我们必须使用Dapper注册类型处理程序
Dapper.SqlMapper.AddTypeHandler(typeof(Country), new CountryHandler());
现在你可以简单地使用Country作为“enum”。例如:
public class Address
{
public string Street { get; set; }
public Country Country { get; set; }
}
var addr = new Address { Street = "Sesamestreet", Country = Country.GB };
当然,缺点是枚举不是通过整数而是通过字符串在内存中备份。