gpt4 book ai didi

sql - Hacky Sql Compact 解决方法

转载 作者:搜寻专家 更新时间:2023-10-30 21:37:41 24 4
gpt4 key购买 nike

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

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

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

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

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

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

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

代码如下所示:

    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 数据库中获取流数据而不必求助于如此糟糕的代码的方法吗?

最佳答案

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

关于sql - Hacky Sql Compact 解决方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/399719/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com