簡體   English   中英

SQL Server 2008:使用.NET 3.5SP1的FileStream插入失敗

[英]SQL Server 2008: FileStream Insertion Failure w/ .NET 3.5SP1

我已經配置了一個帶FileStream組的數據庫,並帶有一個帶文件類型的表。 嘗試插入流式文件時,在創建表行之后,查詢將讀取文件路徑,並且緩沖區返回空文件路徑。 我似乎無法弄清楚為什么。 這是表創建腳本:

/****** Object:  Table [dbo].[JobInstanceFile]    Script Date: 03/22/2010 18:05:36 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[JobInstanceFile](
    [JobInstanceFileId] [int] IDENTITY(1,1) NOT NULL,
    [JobInstanceId] [int] NOT NULL,
    [File] [varbinary](max) FILESTREAM  NULL,
    [FileId] [uniqueidentifier] ROWGUIDCOL  NOT NULL,
    [Created] [datetime] NOT NULL,
 CONSTRAINT [PK_JobInstanceFile] PRIMARY KEY CLUSTERED 
(
    [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],
UNIQUE NONCLUSTERED 
(
    [FileId] 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]

GO

SET ANSI_PADDING OFF
GO

ALTER TABLE [dbo].[JobInstanceFile] ADD  DEFAULT (newid()) FOR [FileId]
GO

這是我調用proc以流式傳輸文件之前創建行的過程:

/****** Object:  StoredProcedure [dbo].[JobInstanceFileCreate]    Script Date: 03/22/2010 18:06:23 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

create proc [dbo].[JobInstanceFileCreate]

    @JobInstanceId int,
    @Created datetime

    as

    insert into JobInstanceFile (JobInstanceId, FileId, Created)
    values (@JobInstanceId, newid(), @Created)

    select scope_identity()
GO

最后,這是我正在使用的代碼:

public int CreateJobInstanceFile(int jobInstanceId, string filePath)
        {
            using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["ConsumerMarketingStoreFiles"].ConnectionString))
            using (var fileStream = new FileStream(filePath, FileMode.Open))
            {
                connection.Open();

                var tran = connection.BeginTransaction(IsolationLevel.ReadCommitted);

                try 
                {
                    //create the JobInstanceFile instance
                    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());

                    //read out the filestream transaction context to stream the file for storage
                    command.CommandText = "select [File].PathName(), GET_FILESTREAM_TRANSACTION_CONTEXT() from JobInstanceFile where JobInstanceFileId = @JobInstanceFileId";
                    command.CommandType = CommandType.Text;
                    command.Parameters.AddWithValue("@JobInstanceFileId", jobInstanceFileId);

                    using (SqlDataReader dr = command.ExecuteReader())
                    {
                        dr.Read();

                        //get the file path we're writing out to
                        string writePath = dr.GetString(0);

                        using (var writeStream = new SqlFileStream(writePath, (byte[])dr.GetValue(1), FileAccess.ReadWrite))
                        {
                            //copy from one stream to another
                            byte[] bytes = new byte[65536];
                            int numBytes;
                            while ((numBytes = fileStream.Read(bytes, 0, 65536)) > 0)
                                writeStream.Write(bytes, 0, numBytes);
                        }
                    }

                    tran.Commit();

                    return jobInstanceFileId;
                }
                catch (Exception e)
                {
                    tran.Rollback();
                    throw e;
                }
            }
        }

有人可以讓我知道我在做什么錯。 在代碼中,以下表達式為文件路徑返回null,不應為:

//獲取我們要寫出的文件路徑為字符串writePath = dr.GetString(0);

服務器與運行代碼的計算機不同,但是必要的共享似乎順序良好,我還運行了以下命令:

EXEC sp_configure filestream_access_level,2

任何幫助將不勝感激。 謝謝!

您不能在NULL值上打開SqlFileStream。 更改INSERT語句以將File = 0x設置為應該開始工作。

PS。 性能注意事項:

  1. 您可以通過發出帶有OUTPUT子句的INSERT 語句來返回到新插入的Blob的事務上下文和文件路徑,從而避免到服務器的額外往返行程。
  2. 如果您不想從SqlFileStream中讀取,請僅將其打開以進行寫入。 在這種情況下,這可能沒什么大不了的,因為您要打開的文件為空。 但是,如果您要更新大文件,則為ReadWrite打開該文件將使Sql首先復制整個文件,然后才允許您使用它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM