SqlException的构造函数在哪里?

时间:2015-11-22 20:17:10

标签: c# .net sqlexception

我正在编写单元测试来验证数据库过载导致的异常检测。

但我找不到SqlException的构造函数。为什么我看不到元数据中的构造函数?

以下代码只是为了帮助理解我为什么要寻找构造函数。

#region Is Timeout
[TestMethod]
public void TestTimeOutWin32ExceptionTimeOut()
{
    Win32Exception ex = new Win32Exception("The wait operation timed out");
    Assert.IsTrue(ExceptionHelper.IsDatabaseTimeOut(ex));
}

[TestMethod]
public void TestTimeOutSqlExceptionTimeOut()
{
    SqlException ex = new SqlException("Timeout expired.  The timeout period elapsed prior to completion of the operation or the server is not responding.");
    Assert.IsTrue(ExceptionHelper.IsDatabaseTimeOut(ex));
}

[TestMethod]
public void TestTimeOutEntityCommandExecutionException()
{
    SqlException innerException = new SqlException("Timeout expired.  The timeout period elapsed prior to completion of the operation or the server is not responding.");
    EntityCommandExecutionException ex = new EntityCommandExecutionException("anything", innerException);
    Assert.IsTrue(ExceptionHelper.IsDatabaseTimeOut(ex));
}

#endregion

#region Is NOT Timeout
[TestMethod]
public void TestTimeOutWin32ExceptionEmpty()
{
    Win32Exception ex = new Win32Exception("");
    Assert.IsFalse(ExceptionHelper.IsDatabaseTimeOut(ex));
}

[TestMethod]
public void TestTimeOutArgumenException()
{
    ArgumentException ex = new ArgumentException("invalid path");
    Assert.IsFalse(ExceptionHelper.IsDatabaseTimeOut(ex));
}

[TestMethod]
public void TestTimeOutArgumenNullException()
{
    ArgumentNullException ex = new ArgumentNullException("empty path");
    Assert.IsFalse(ExceptionHelper.IsDatabaseTimeOut(ex));
}

[TestMethod]
public void TestTimeOutException()
{
    Exception ex = new Exception("custom string");
    Assert.IsFalse(ExceptionHelper.IsDatabaseTimeOut(ex));
}
#endregion

3 个答案:

答案 0 :(得分:3)

SqlException使用内部工厂方法(CreateException)通过私有构造函数在内部创建实例。没有允许您创建一个的公共方法,可能是因为它特定于SQL数据提供程序而不是为您创建自己的异常。

答案 1 :(得分:1)

我不知道为什么他们没有提供公共构造函数,但您可以使用FormatterServices.GetUninitializedObject

创建实例
var sqlex = FormatterServices.GetUninitializedObject(typeof(SqlException)) as SqlException;

之后,您可以使用FormatterServices.PopulateObjectMembers填充所需的成员。

提示:小心!

编辑基于hvd评论:

但为什么要自己呢?强制SQL Server超时一次,序列化异常,将序列化异常存储在测试数据中,并在需要特定异常时对其进行反序列化。

答案 2 :(得分:0)

是的,构造函数是私有的:

private SqlException CreateSqlException(string message)
{
        var collectionConstructor = typeof(SqlErrorCollection).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, //visibility
            null, //binder
            new Type[0],
            null);          

        var errorCollection = (SqlErrorCollection)collectionConstructor.Invoke(null);

        var constructor = typeof(SqlException).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, //visibility
            null, //binder
            new[] { typeof(string), typeof(SqlErrorCollection), typeof(Exception), typeof(Guid) },
            null); //param modifiers

        return (SqlException)constructor.Invoke(new object[] { message, errorCollection, new DataException(), Guid.NewGuid() });
}

取自jgauffin's coding den