【问题标题】:losing data when transfering SqlDataReader object to the method that needs IDataReader interface将SqlDataReader对象传递给需要IDataReader接口的方法时丢失数据
【发布时间】:2012-10-09 17:32:40
【问题描述】:

我有一个需要 SqlDataReader 对象作为参数的方法,并且我在其中模拟了该对象的地方进行了测试,并且一切正常。

但是,现在我需要更改该方法。它现在应该只调用具有 IDataReader 作为参数的新方法,这是一个问题,因为当我将模拟的 SqlDataReader 作为新方法的参数传输时,它会丢失他的数据,我不知道为什么。

类似这样的:

void method(SqlDataReader mockedObject)
{
   // example property
   mockedObject.FieldCount; // for example the value is 1;
   newMethod(mockedObject);
}

void newMethod(IDataReader newObject)
{
   // example property
   newObject.FieldCount // here value is 0;
}

我观察到,如果我只是将 SqlDataReader 对象复制到 IDataReader 类型的新变量,数据也会被清除。

类似这样的:

void method(SqlDataReader mockedObject)
{
   IDataReader variable = mockedObject;
}

正确的代码:

=========================================================================================
        [TestMethod()]
    [DeploymentItem("IICMS.dll")]
    public void CheckNullableDateTimeTest_SqlDataReader_Valid()
    {
        MockRepository mocks = new MockRepository();
        SqlDataReader reader = mocks.DynamicMock<SqlDataReader>();
        string column = "test";
        DateTime? expected = new DateTime(2, 1, 1);
        Nullable<DateTime> actual;

        reader.Stub(r => r[column]).Return(expected);
        reader.Stub(r => r.FieldCount).Return(1);
        mocks.ReplayAll();

        actual = Utility_Accessor.CheckNullableDateTime(reader, column);
        Assert.AreEqual(expected, actual);
    }
======================================================================================
        public static DateTime? CheckNullableDateTime(SqlDataReader read, string column)
    {
        return GetValue<DateTime?>(read, column, null);
    }
======================================================================================
public static T GetValue<T>(IDataReader reader, string columnName, T defaultValue)
    {
        try
        {
            for (int i = 0; i < reader.FieldCount; i++)
            {
                if (reader.GetName(i) == columnName)
                {
                    object value = reader[i];
                    return Convert.IsDBNull(value) ? defaultValue : (T)value;
                }
            }

            return defaultValue;
        }
        catch
        {
            return defaultValue;
        }
    }

所以有代码,第二种和第三种方法在其他dll中,但它对任何东西都没有影响。对象在 RhinoMocks 中被模拟 ;)

将 SqlDataReader 对象(读取)传输到 GetValue 方法后数据丢失(即 FieldCount 等于 0,在 Check.. 方法中它具有正确的值 = 1)

【问题讨论】:

  • So.. 这是否意味着如果您调用FieldCount 两次(即使使用相同的方法),您会得到两个不同的结果,1 和 0?
  • 如果不是,FieldCount 是否被 new 关键字覆盖?
  • 请注意,您实际上并没有复制对象,您只是在转换引用,没有任何事情发生,因为SqlDataReader 没有任何显式或隐式转换运算符。
  • @casperOne 好的,但是 IDataReader 是一个接口,而 SqlDataReader 实现了它,所以我应该能够将它转移到第二种方法,而不会丢失我的数据(即 FieldCount 参数)[/br] Patrick:如果你调用它两次,值将是相同的,但如果你尝试 put 呢? reader 进入新的 IDataReader 对象,然后调用此属性,它会有所不同
  • 我不同意这一点,但只是明确表示不会复制到新对象或类似的东西。

标签: c# casting sqldatareader idatareader


【解决方案1】:

我无法解释这一点,但将测试方法更改为下面的表格,使得, 所有对象字段在每个方法(CheckNullString 和 GetValue)中都是可用的:

    [TestMethod()]
    [DeploymentItem("IICMS.dll")]
    public void CheckNullableDateTimeTest_SqlDataReader_Valid()
    {
        MockRepository mocks = new MockRepository();
        SqlDataReader reader = mocks.DynamicMock<SqlDataReader>();
        IDataReader reader2 = reader;
        string column = "test";
        DateTime? expected = new DateTime(2,1,1);
        DateTime? actual;

        reader.Stub(r => r[column]).Return(invalidValue);
        reader.Stub(r => r[0]).Return(invalidValue);
        reader.Stub(r => r.FieldCount).Return(1);
        reader.Stub(r => r.GetName(0)).Return(column);

        reader2.Stub(r => r[column]).Return(invalidValue);
        reader2.Stub(r => r[0]).Return(invalidValue);
        reader2.Stub(r => r.FieldCount).Return(1);
        reader2.Stub(r => r.GetName(0)).Return(column);
        mocks.ReplayAll();

        actual = Utility_Accessor.CheckNullString(reader, column);
        Assert.AreEqual(expected, actual);
    }

【讨论】:

    猜你喜欢
    • 2016-01-26
    • 2016-12-23
    • 2017-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-10
    • 1970-01-01
    • 2016-05-31
    相关资源
    最近更新 更多