Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 使用实体框架从SQL Server检索blob时出现编码问题_Sql Server_Entity Framework_Encoding_C# 3.0 - Fatal编程技术网

Sql server 使用实体框架从SQL Server检索blob时出现编码问题

Sql server 使用实体框架从SQL Server检索blob时出现编码问题,sql-server,entity-framework,encoding,c#-3.0,Sql Server,Entity Framework,Encoding,C# 3.0,我注意到一个奇怪的现象,即尝试将2003 MS word文档存储在SQL Server blob(nvarchar(max))字段中,然后使用实体框架(EF1)检索它们,然后将它们转换回文件(然后附加到电子邮件) 基本代码: 1) 我使用openrowset将文档插入数据库: INSERT INTO [dbo].[Attachment]([id],[Blob]) SELECT 1, (SELECT BulkColumn FROM OPENROWSET(Bulk 'path_to_

我注意到一个奇怪的现象,即尝试将2003 MS word文档存储在SQL Server blob(
nvarchar(max)
)字段中,然后使用实体框架(EF1)检索它们,然后将它们转换回文件(然后附加到电子邮件)

基本代码:

1) 我使用openrowset将文档插入数据库:

INSERT INTO [dbo].[Attachment]([id],[Blob])     
   SELECT 1, (SELECT BulkColumn FROM OPENROWSET(Bulk 'path_to_attachment\abc123.doc', SINGLE_BLOB) AS BLOB) 
2) 然后,我使用EF1从数据库中检索该文件(为简洁起见,进行了简化-绕过repo等):

问题:

这是可行的,但是我注意到在这个过程中推送文件后,文件中出现了一些差异,一些小的格式问题等等

在进行了更深入的挖掘(使用VBinDiff)之后,看起来一些Unicode字符正在转换为FDFF

00DC > FDFF
原件:

00 00 00 DC 00 00 00

转换:

00 00 00 FD FF 00 00 00

其他例子包括:

BED9 > FDFF
CFD9 > FDFF
这看起来是从这里开始的范围中的最后一个:

问题

1) 在返回字符串对象
attachment.Blob
-然后尝试将其转换回字节数组之前,我是在做一些愚蠢的事情,还是EF在做一些古怪的事情

2) 在仍然使用实体框架的情况下,有没有更好的方法从blob字段中检索出准确的字节?(或者我应该使用存储过程,或者使用SqlDataReader,而不是使用SqlDataReader—为了不使数据访问路径复杂化,我真的不想这样做)

使用导入将文件的内容返回为
varbinary(max)
类型的单行、单列行集

我建议使用将文件读取为
nvarchar(max)
SINGLE\u-BLOB
,而不是
SINGLE\u-BLOB

必须使用此处显示的
SINGLE\u NCLOB
选项读取Unicode文件:

SELECT BulkColumn 
FROM OPENROWSET (BULK 'path_to_attachment\abc123.doc', SINGLE_NCLOB) AS BLOB
参考号:

更新(回应评论):如果文件不是unicode(如您尝试的那样),则在检索它们时,不应使用unicode编码来获取字节:

var bytes = Encoding.ASCII.GetBytes(attachment.Blob);

米奇的回答帮助我指出了代码中的错误。出于某种原因(我认为是习惯的力量),我会将Blob字段设置为
nvarchar(max)
,正如Mitch所指出的,
SINGLE\u Blob
将文件信息保存为
varbinary(max)
,这实际上是我在应用程序中想要的(请参见问题点2)

解决方案:

  • 将数据库字段从
    nvarchar(max)
    转换为
    varbinary(max)
  • 更新实体框架模型
  • 将EF模型内的blob字段从
    string
    更改为二进制`
  • 最后,改变这个

    var attachment = (from a in ctx.Attachment where a.id == 1 select a).FirstOrDefault()
    var bytes = Encoding.Unicode.GetBytes(attachment.Blob);
    var stream = new MemoryStream(bytes);
    var fileName = "abc123.doc";
    var fileToAttach = new Attachment(stream, fileName, MediaTypeNames.Application.Octet);
    
    为此:

    var attachment = (from a in ctx.Attachment where a.id == 1 select a).FirstOrDefault()
    var stream = new MemoryStream(attachment.Blob);
    var fileName = "abc123.doc";
    var fileToAttach = new Attachment(stream, fileName, MediaTypeNames.Application.Octet);
    

    @米奇·麦特:如果我尝试将参数更改为
    SINGLE\u NCLOB
    ,我会收到错误消息:
    SINGLE\u NCLOB需要一个UNICODE(widechar)输入文件。指定的文件不是Unicode。
    -非常感谢您的回复。
    var attachment = (from a in ctx.Attachment where a.id == 1 select a).FirstOrDefault()
    var stream = new MemoryStream(attachment.Blob);
    var fileName = "abc123.doc";
    var fileToAttach = new Attachment(stream, fileName, MediaTypeNames.Application.Octet);