转换器
IValueConverter
接口定义了数据转换的规则,它提供两个方法:
ConvertFrom 方法将数据库支持的数据类型转换为对象
ConvertTo 方法将对象转换可数据库支持的数据类型
下例演示了对于 System.Drawing.Color
如何存储和读取的:
public sealed class ColorConverter : IValueConverter
{
public object ConvertFrom(object value, DbType dbType = DbType.String)
{
switch (dbType)
{
case DbType.String:
case DbType.StringFixedLength:
case DbType.AnsiString:
case DbType.AnsiStringFixedLength:
return ConvertFromString(value);
case DbType.Binary:
return ConvertFromBinary(value);
default:
throw new ConverterNotSupportedException(typeof(Color), dbType);
}
}
public object ConvertTo(object value, DbType dbType = DbType.String)
{
switch (dbType)
{
case DbType.String:
case DbType.StringFixedLength:
case DbType.AnsiString:
case DbType.AnsiStringFixedLength:
return ConvertToString(value);
case DbType.Binary:
return ConvertToBinary(value);
default:
throw new ConverterNotSupportedException(typeof(Color), dbType);
}
}
private object ConvertFromString(object value)
{
if (value.IsNullOrEmpty())
{
return Color.Empty;
}
var converter = TypeDescriptor.GetConverter(typeof(int));
if (converter == null)
{
return Color.Empty;
}
var val = converter.ConvertFromString("0x" + value);
return val == null ? Color.Empty : Color.FromArgb(-16777216 | (int)val);
}
private object ConvertFromBinary(object value)
{
var bytes = (byte[])value;
if (bytes == null)
{
return Color.Empty;
}
return bytes.Length switch
{
4 => Color.FromArgb(bytes[0], bytes[1], bytes[2], bytes[3]),
3 => Color.FromArgb(bytes[0], bytes[1], bytes[2]),
_ => Color.Empty,
};
}
private object ConvertToString(object value)
{
if (value == null || string.IsNullOrEmpty(value.ToString()))
{
return string.Empty;
}
var color = (Color)value;
return string.Format(
"{0}{1}{2}{3}",
color.A.ToString("X2"),
color.R.ToString("X2"),
color.G.ToString("X2"),
color.B.ToString("X2"));
}
private object ConvertToBinary(object value)
{
if (value == null)
{
return new byte[0];
}
var color = (Color)value;
return new[] { color.A, color.R, color.G, color.B };
}
}
从上面的示例中可以看出,System.Drawing.Color
可以使用字符串和二进制进行存储,两个方法的 dbType 参数即指定了字段的数据类型,针对不同的数据类型,对存储和读取都做了处理。
ValueConverterBase<T>
是一个泛型抽象类,如果你需要扩展其他的转换器,可以继承自它。