When a SQL Exception is encountered in a function, it can be categorized based on the SQL Number. This is especially useful in scenarios like Unit Testing, where there might be a need to create a new SQL Exception for testing purposes.
//create the SQL Exception
private SqlException MakeSqlException(int sqlNumber)
{
//create new exception
var newException = new Exception();
//construct the SQL Error Collection
SqlErrorCollection collection = Construct<sqlerrorcollection(); construct="" a="" sql="" error="" with="" parameter="" (this="" case="" its="" number)="" sqlerror="">(sqlNumber, (byte)2, (byte)3, "server name", "error message", "proc", 100, newException);
//Using reflection inject the error into the SqlErrorCollection
typeof(SqlErrorCollection)
.GetMethod("Add", BindingFlags.NonPublic |
BindingFlags.Instance)
.Invoke(collection, new object[] { error });
//Using reflection create the SQL exception
var e = typeof(SqlException)
.GetMethod("CreateException", BindingFlags.NonPublic |
BindingFlags.Static, null, CallingConventions.ExplicitThis,
new[] { typeof(SqlErrorCollection), typeof(string) }, new ParameterModifier[] { })
.Invoke(null, new object[] { collection, "11.0.0" }) as SqlException;
return e;
}
//constructs a class based off of the type and parameters
private T Construct(params object[] p)
{
//declare a new var for type
var t = new Type[p.Length];
//for each parameter get the type
for (var i = 0; i < p.Length; i++)
{
t[i] = p[i].GetType();
}
//get constructor info
var constructorInfo = typeof(T).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, t, null);
if (constructorInfo == null)
{
throw new InvalidOperationException(string.Format("Cannot find a matching private or static constructor for type {0} with the constructor parameters ({1})", typeof(T).Name, string.Join(", ", t)));
}
//invoke and return constructor
return (T)constructorInfo.Invoke(p);
} </sqlerrorcollection();>