公共类SqlExceptionMock
{
public static SqlException ThrowSqlException(int errorNumber, string message = null)
{
var ex = (SqlException)FormatterServices.GetUninitializedObject(typeof(SqlException));
var errors = GenerateSqlErrorCollection(errorNumber, message);
SetPrivateFieldValue(ex, "_errors", errors);
return ex;
}
private static SqlErrorCollection GenerateSqlErrorCollection(int errorNumber, string message)
{
var t = typeof(SqlErrorCollection);
var col = (SqlErrorCollection)FormatterServices.GetUninitializedObject(t);
SetPrivateFieldValue(col, "_errors", new List<object>());
var sqlError = GenerateSqlError(errorNumber, message);
var method = t.GetMethod(
"Add",
BindingFlags.NonPublic | BindingFlags.Instance);
method.Invoke(col, new object[] { sqlError });
return col;
}
private static SqlError GenerateSqlError(int errorNumber, string message)
{
var sqlError = (SqlError)FormatterServices.GetUninitializedObject(typeof(SqlError));
SetPrivateFieldValue(sqlError, "_number", errorNumber);
if (!string.IsNullOrEmpty(message)) SetPrivateFieldValue(sqlError, "_message", message);
return sqlError;
}
private static void SetPrivateFieldValue(object obj, string field, object val)
{
var member = obj.GetType().GetField(
field,
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance
);
member?.SetValue(obj, val);
}
}