【问题标题】:SQL Server 2008: FileStream Insertion Failure w/ .NET 3.5SP1SQL Server 2008:使用 .NET 3.5SP1 的文件流插入失败
【发布时间】:2011-01-30 19:37:54
【问题描述】:

我已经配置了一个带有 FileStream 组的数据库,并且上面有一个带有文件类型的表。当尝试插入流文件并创建表行后,我的查询读取文件路径并且缓冲区返回空文件路径。我似乎无法弄清楚为什么。下面是建表脚本:

/****** 对象:表 [dbo].[JobInstanceFile] 脚本日期:03/22/2010 18:05:36 ******/ 设置 ANSI_NULLS ON 走 设置 QUOTED_IDENTIFIER ON 走 设置 ANSI_PADDING ON 走 创建表 [dbo].[JobInstanceFile]( [JobInstanceFileId] [int] IDENTITY(1,1) 非空, [JobInstanceId] [int] 非空, [文件] [varbinary](最大)FILESTREAM NULL, [FileId] [uniqueidentifier] ROWGUIDCOL NOT NULL, [创建] [日期时间] 不为空, 约束 [PK_JobInstanceFile] 主键集群 ( [JobInstanceFileId] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] FILESTREAM_ON [JobInstanceFilesGroup], 独特的非簇 ( [文件 ID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] FILESTREAM_ON [JobInstanceFilesGroup] 走 设置 ANSI_PADDING 关闭 走 ALTER TABLE [dbo].[JobInstanceFile] 为 [FileId] 添加默认值 (newid()) 走

这是我在流式传输文件之前调用创建行的过程:

/****** 对象:StoredProcedure [dbo].[JobInstanceFileCreate] 脚本日期:03/22/2010 18:06:23 ******/ 设置 ANSI_NULLS ON 走 设置 QUOTED_IDENTIFIER ON 走 创建过程 [dbo].[JobInstanceFileCreate] @JobInstanceId 整数, @Created 日期时间 作为 插入 JobInstanceFile (JobInstanceId, FileId, Created) 值(@JobInstanceId、newid()、@Created) 选择 scope_identity() 走

最后,这是我正在使用的代码:

public int CreateJobInstanceFile(int jobInstanceId, string filePath) { 使用 (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["ConsumerMarketingStoreFiles"].ConnectionString)) 使用 (var fileStream = new FileStream(filePath, FileMode.Open)) { 连接.打开(); var tran = connection.BeginTransaction(IsolationLevel.ReadCommitted); 尝试 { //创建 JobInstanceFile 实例 var command = new SqlCommand("JobInstanceFileCreate", connection) { Transaction = tran }; command.CommandType = CommandType.StoredProcedure; command.Parameters.AddWithValue("@JobInstanceId", jobInstanceId); command.Parameters.AddWithValue("@Created", DateTime.Now); int jobInstanceFileId = Convert.ToInt32(command.ExecuteScalar()); //读出文件流事务上下文以流式传输文件进行存储 command.CommandText = "从 JobInstanceFile 中选择 [File].PathName(), GET_FILESTREAM_TRANSACTION_CONTEXT(),其中 JobInstanceFileId = @JobInstanceFileId"; command.CommandType = CommandType.Text; command.Parameters.AddWithValue("@JobInstanceFileId", jobInstanceFileId); 使用 (SqlDataReader dr = command.ExecuteReader()) { 博士读(); //获取我们要写入的文件路径 字符串 writePath = dr.GetString(0); 使用 (var writeStream = new SqlFileStream(writePath, (byte[])dr.GetValue(1), FileAccess.ReadWrite)) { //从一个流复制到另一个 字节[]字节=新字节[65536]; 整数字节; 而 ((numBytes = fileStream.Read(bytes, 0, 65536)) > 0) writeStream.Write(bytes, 0, numBytes); } } tran.Commit(); 返回jobInstanceFileId; } 捕获(异常 e) { tran.Rollback(); 扔 e; } } }

谁能告诉我我做错了什么。在代码中,以下表达式为文件路径返回 null 并且不应该是:

//获取我们要写入的文件路径 string writePath = dr.GetString(0);

服务器与运行代码的计算机不同,但必要的共享似乎是有序的,我还运行了以下命令:

EXEC sp_configure filestream_access_level, 2

任何帮助将不胜感激。谢谢!

【问题讨论】:

    标签: c# sql-server-2008 filestream


    【解决方案1】:

    您不能在 NULL 值上打开 SqlFileStream。更改 INSERT 语句以设置 File = 0x,它应该开始工作。

    PS。 一些性能注意事项:

    1. 您可以通过发出带有OUTPUT clause 的 INSERT 来避免与服务器的额外往返,该 INSERT 返回事务上下文和新插入的 blob 的文件路径。
    2. 如果您不打算从 SqlFileStream 中读取,请将其打开为只写。在这种特殊情况下,这可能没什么大不了的,因为您打开的文件是空的。但是,如果您要更新一个大文件,为 ReadWrite 打开它会让 Sql 先复制整个文件,然后才让您使用它。

    【讨论】:

    • 这就像一个冠军,非常感谢使用输出子句的指针,我什至不知道它存在。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-01
    • 2013-02-17
    • 2011-07-26
    相关资源
    最近更新 更多