1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
|
using System.Data.Common;
using System.Data.SqlClient;
using System.Linq.Expressions;
using System.IO;
using System.Reflection;
using System.Text;
using System.Runtime.Serialization.Formatters.Binary;
using System.Linq;
using System.Collections.Generic;
using System.Collections;
using System.Diagnostics.CodeAnalysis;
namespace System.Data.Linq {
public static class DBConvert {
private static Type[] StringArg = new Type[] { typeof(string) };
[SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "Microsoft: Generic parameters are required for strong-typing of the return type.")]
public static T ChangeType<T>(object value) {
return (T)ChangeType(value, typeof(T));
}
[SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", Justification = "Microsoft: Cast is dependent on node type and casts do not happen unecessarily in a single code path.")]
[SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Justification = "These issues are related to our use of if-then and case statements for node types, which adds to the complexity count however when reviewed they are easy to navigate and understand.")]
public static object ChangeType(object value, Type type) {
if (value == null)
return null;
MethodInfo mi;
Type toType = System.Data.Linq.SqlClient.TypeSystem.GetNonNullableType(type);
Type fromType = value.GetType();
if (toType.IsAssignableFrom(fromType))
return value;
if (toType == typeof(Binary)) {
if (fromType == typeof(byte[])) {
return new Binary((byte[])value);
}
else if (fromType == typeof(Guid)) {
return new Binary(((Guid)value).ToByteArray());
}
else {
BinaryFormatter formatter = new BinaryFormatter();
byte[] streamArray;
using (MemoryStream stream = new MemoryStream()) {
formatter.Serialize(stream, value);
streamArray = stream.ToArray();
}
return new Binary(streamArray);
}
}
else if (toType == typeof(byte[])) {
if (fromType == typeof(Binary)) {
return ((Binary)value).ToArray();
}
else if (fromType == typeof(Guid)) {
return ((Guid)value).ToByteArray();
}
else {
BinaryFormatter formatter = new BinaryFormatter();
byte[] returnValue;
using (MemoryStream stream = new MemoryStream()) {
formatter.Serialize(stream, value);
returnValue = stream.ToArray();
}
return returnValue;
}
}
else if (fromType == typeof(byte[])) {
if (toType == typeof(Guid)) {
return new Guid((byte[])value);
}
else {
BinaryFormatter formatter = new BinaryFormatter();
object returnValue;
using (MemoryStream stream = new MemoryStream((byte[])value)) {
returnValue = ChangeType(formatter.Deserialize(stream), toType);
}
return returnValue;
}
}
else if (fromType == typeof(Binary)) {
if (toType == typeof(Guid)) {
return new Guid(((Binary)value).ToArray());
}
else {
BinaryFormatter formatter = new BinaryFormatter();
using (MemoryStream stream = new MemoryStream(((Binary)value).ToArray(), false)) {
return ChangeType(formatter.Deserialize(stream), toType);
}
}
}
else if (toType.IsEnum) {
if (fromType == typeof(string)) {
string text = ((string)value).Trim();
return Enum.Parse(toType, text);
}
else {
return Enum.ToObject(toType, Convert.ChangeType(value, Enum.GetUnderlyingType(toType), Globalization.CultureInfo.InvariantCulture));
}
}
else if (fromType.IsEnum) {
if (toType == typeof(string)) {
return Enum.GetName(fromType, value);
}
else {
return Convert.ChangeType(Convert.ChangeType(value,
Enum.GetUnderlyingType(fromType),
Globalization.CultureInfo.InvariantCulture),
toType,
Globalization.CultureInfo.InvariantCulture);
}
}
else if (toType == typeof(TimeSpan)) {
if (fromType == typeof(string)) {
return TimeSpan.Parse(value.ToString(), Globalization.CultureInfo.InvariantCulture);
}
else if (fromType == typeof(DateTime)) {
return DateTime.Parse(value.ToString(), Globalization.CultureInfo.InvariantCulture).TimeOfDay;
}
else if (fromType == typeof(DateTimeOffset)) {
return DateTimeOffset.Parse(value.ToString(), Globalization.CultureInfo.InvariantCulture).TimeOfDay;
}
else {
return new TimeSpan((long)Convert.ChangeType(value, typeof(long), Globalization.CultureInfo.InvariantCulture));
}
}
else if (fromType == typeof(TimeSpan)) {
if (toType == typeof(string)) {
return ((TimeSpan)value).ToString("", Globalization.CultureInfo.InvariantCulture);
}
else if (toType == typeof(DateTime)) {
DateTime dt = new DateTime();
return dt.Add((TimeSpan)value);
}
else if (toType == typeof(DateTimeOffset)) {
DateTimeOffset dto = new DateTimeOffset();
return dto.Add((TimeSpan)value);
}
else {
return Convert.ChangeType(((TimeSpan)value).Ticks, toType, Globalization.CultureInfo.InvariantCulture);
}
}
else if (toType == typeof(DateTime) && fromType == typeof(DateTimeOffset)) {
return ((DateTimeOffset)value).DateTime;
}
else if (toType == typeof(DateTimeOffset) && fromType == typeof(DateTime)) {
return new DateTimeOffset((DateTime)value);
}
else if (toType == typeof(string) && !(typeof(IConvertible).IsAssignableFrom(fromType))) {
if (fromType == typeof(char[])) {
return new String((char[])value);
}
else {
return value.ToString();
}
}
else if (fromType == typeof(string)) {
if (toType == typeof(Guid)) {
return new Guid((string)value);
}
else if (toType == typeof(char[])) {
return ((String)value).ToCharArray();
}
else if (toType == typeof(System.Xml.Linq.XDocument) && (string)value == string.Empty) {
return new System.Xml.Linq.XDocument();
}
else if (!(typeof(IConvertible).IsAssignableFrom(toType)) &&
(mi = toType.GetMethod("Parse", BindingFlags.Static | BindingFlags.Public, null, StringArg, null)) != null) {
try {
return SecurityUtils.MethodInfoInvoke(mi, null, new object[] { value });
}
catch (TargetInvocationException t) {
throw t.GetBaseException();
}
}
else {
return Convert.ChangeType(value, toType, Globalization.CultureInfo.InvariantCulture);
}
}
else if (toType.IsGenericType && toType.GetGenericTypeDefinition() == typeof(IQueryable<>)
&& typeof(IEnumerable<>).MakeGenericType(toType.GetGenericArguments()[0]).IsAssignableFrom(fromType)
) {
return Queryable.AsQueryable((IEnumerable)value);
}
else {
try {
return Convert.ChangeType(value, toType, Globalization.CultureInfo.InvariantCulture);
} catch (InvalidCastException) {
throw Error.CouldNotConvert(fromType, toType);
}
}
}
}
}
|