【问题标题】:Hacky Sql Compact WorkaroundHacky Sql Compact 解决方法
【发布时间】:2008-12-30 07:27:57
【问题描述】:

所以,我正在尝试使用 ADO.NET 流式传输存储在 SQL Compact 数据库的图像列中的文件数据。

为此,我编写了一个 DataReaderStream 类,该类接受一个数据读取器,为顺序访问打开,并将其表示为流,将流上对 Read(...) 的调用重定向到 IDataReader.GetBytes(... )。

与 Stream 类相比,IDataReader.GetBytes(...) 的一个“奇怪”方面是 GetBytes 要求客户端在每次调用时增加一个偏移量并传递该偏移量。即使访问是顺序的,它也会这样做,并且不可能在数据读取器流中“向后”读取。

IDataReader 的 SqlCeDataReader 实现通过增加一个内部计数器来强制执行此操作,该计数器标识它返回的字节总数。如果您传入的数字小于或大于该数字,该方法将抛出 InvalidOperationException。

然而,这样做的问题是 SqlCeDataReader 实现中存在一个错误,导致它将内部计数器设置为错误的值。这会导致随后对我的流上的 Read 调用在不应该抛出异常时抛出异常。

我在this MSDN thread 上找到了一些关于该错误的信息。

我想出了一个令人作呕的、骇人听闻的解决方法,它基本上使用反射将类中的字段更新为正确的值。

代码如下所示:

    public override int Read(byte[] buffer, int offset, int count)
    {
        m_length  = m_length ?? m_dr.GetBytes(0, 0, null, offset, count);

        if (m_fieldOffSet < m_length)
        {
            var bytesRead = m_dr.GetBytes(0, m_fieldOffSet, buffer, offset, count);
            m_fieldOffSet += bytesRead;

            if (m_dr is SqlCeDataReader)
            {
                //BEGIN HACK
                //This is a horrible HACK.
                    m_field = m_field ?? typeof (SqlCeDataReader).GetField("sequentialUnitsRead", BindingFlags.NonPublic | BindingFlags.Instance);
                    var length = (long)(m_field.GetValue(m_dr));
                    if (length != m_fieldOffSet)
                    {   
                        m_field.SetValue(m_dr, m_fieldOffSet);
                    }
                //END HACK
            }

            return (int) bytesRead;
        }
        else
        {
            return 0;
        }
    }

出于显而易见的原因,我宁愿不使用它。

但是,我也不想在内存中缓冲 blob 的全部内容。

有没有人知道我可以从 SQL Compact 数据库中获取流数据而无需求助于如此糟糕的代码的方法?

【问题讨论】:

    标签: sql sql-server database


    【解决方案1】:

    我(通过 SQL Compact 博客)联系了 Microsoft,他们确认了该错误,并建议我使用 OLEDB 作为解决方法。所以,我会尝试一下,看看它是否适合我。

    【讨论】:

      【解决方案2】:

      实际上,我决定一开始就不在数据库中存储 blob 来解决这个问题。

      这消除了问题(我可以从文件流式传输数据),还解决了一些我可能遇到的 Sql Compact 的 4 GB 大小限制问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-10-09
        • 1970-01-01
        • 1970-01-01
        • 2010-10-04
        • 2012-01-25
        • 1970-01-01
        • 2018-06-01
        • 1970-01-01
        相关资源
        最近更新 更多