代码之家  ›  专栏  ›  技术社区  ›  Scott Wisniewski

Hacky Sql Compact解决方案

  •  2
  • Scott Wisniewski  · 技术社区  · 16 年前

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

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

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

    但是,问题是SqlCeDataReader实现中存在一个错误,导致它将内部计数器设置为错误的值。这会导致后续调用Read on my stream时抛出异常,而这些异常本不应该出现。

    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的全部内容。

    2 回复  |  直到 16 年前
        1
  •  1
  •   Scott Wisniewski    16 年前

    我联系了微软(通过SQLCompact博客),他们确认了这个bug,并建议我使用OLEDB作为解决方案。所以,我会试试,看看这对我是否有效。

        2
  •  -1
  •   Scott Wisniewski    16 年前

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

    这消除了这个问题(我可以从文件中流式传输数据),还修复了我在使用SQLCompact的4GB大小限制时可能遇到的一些问题。