首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从WCF服务返回SQLFileStream的干净方法是什么?

从WCF服务返回SQLFileStream的干净方法是什么?
EN

Stack Overflow用户
提问于 2011-08-02 15:44:35
回答 2查看 1.5K关注 0票数 1

我们通过将SqlFileStream对象传递回客户端,使用FileStream从WCF服务下载存储在SQL Server中的文档。为此,我们让服务中的DB事务和连接保持打开状态。我们关闭客户端中的SqlFileStream。

代码语言:javascript
复制
'Service
Public Function GetDokumentStream(dokumentId As Integer) As System.IO.Stream Implements IDataService.GetDokumentStream
  Dim cnx = New SqlConnection(...)
  cnx.Open()
  Dim tran = cnx.BeginTransaction()
  Dim cmd As New SqlCommand("Select Dokument.PathName(), GET_FILESTREAM_TRANSACTION_CONTEXT() from Dokument where ID= @ID", cnx, tran)
  cmd.Parameters.AddWithValue("ID", dokumentId)
  Using rdr = cmd.ExecuteReader()
    If rdr.Read() Then
        Dim pathName = rdr(0).ToString()
        Dim context = CType(rdr(1), Byte())
        Dim sqlFileStream As New SqlFileStream(pathName, context, IO.FileAccess.Read)
        Return sqlFileStream
    Else
        '...
    End If
  End Using

'Client
Dim sqlFileStream = _satDataService.GetDokumentStream(dokumentInfo.DokumentID)
Using fileStream As New IO.FileStream(fileName, IO.FileMode.OpenOrCreate)
    sqlFileStream.CopyTo(fileStream)
    sqlFileStream.Close()
End Using

我们必须实现一些东西来手动关闭服务中的连接,还是WCF基础设施会自动清理?是否可以在客户端关闭返回的流,或者我们应该更好地为实现IDisposable的流创建一个复杂类型?

或者,我们可以将SQLFileStream复制到MemoryStrean,关闭连接并返回内存流:

代码语言:javascript
复制
Using cnx = New SqlConnection(...)
    cnx.Open()
    Using tran = cnx.BeginTransaction()
        Dim cmd As New SqlCommand("Select Dokument.PathName(), GET_FILESTREAM_TRANSACTION_CONTEXT() from Dokument where ID= @ID", cnx, 

tran)
        cmd.Parameters.AddWithValue("ID", dokumentId)
        Using rdr = cmd.ExecuteReader()
            If rdr.Read() Then
                Dim pathName = rdr(0).ToString()
                Dim context = CType(rdr(1), Byte())
                Dim context1 = rdr(1)
                Dim sqlFileStream As New SqlFileStream(pathName, context, IO.FileAccess.Read)
                sqlFileStream.CopyTo(memoryStream)
                _trace.InfoFormat("Returning file {0} size {1}bytes", pathName, memoryStream.Length)
                memoryStream.Position = 0
                Return memoryStream
            Else
                Throw New ApplicationException("Dokument File not found")
            End If
        End Using
    End Using
End Using

与直接返回SqlFileStream相比,此解决方案是否使用了更多的服务器内存?或者WCF会在内部将SqlFileStream复制到内存吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-08-02 16:23:43

你必须自己处理你的连接和交易。处理操作的内部实现不是WCF的责任。作为参数传递或从操作返回的流为by default closed by WCF

第二个示例将把流中的所有数据加载到服务主机的内存中。这会破坏服务端的流媒体功能。

票数 0
EN

Stack Overflow用户

发布于 2016-03-05 07:47:32

我自己遇到了这个问题,并在SqlFileStream周围创建了一个包装类,它使用泛型类型和反射来允许您将行映射到类型并访问FILESTREAM列。

您不需要编写任何SQL语句,它都是使用映射信息在内部生成的。

它还包装连接和事务,以便在处理流之后,提交事务并处理连接,从而使其可以安全地从WCF服务返回。

它可以在https://github.com/RupertAvery/WrappedSqlFileStream上找到

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6908758

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档