2010-03-23 4 views
1

Я настроил группу db w/a FileStream и на ней есть таблица w/Тип файла. При попытке вставить потоковый файл и после создания строки таблицы мой запрос, чтобы прочитать путь к файлу, и буфер возвращает нулевой путь к файлу. Я не могу понять, почему. Вот скрипт создания таблицы:SQL Server 2008: Ошибка вставки элемента FileStream с .NET 3.5SP1

 

    /****** 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 

Вот мой прок я называю, чтобы создать строку перед потоковой передачей файла:

 

    /****** 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 для пути к файлу и не должно быть:

// получить путь к файлу, который мы записываем в string writePath = dr.GetString (0);

Сервер отличается, то компьютер код работает на но необходимые акции, как представляется, в порядке, и я также запустить следующее:

EXEC sp_configure filestream_access_level, 2

Любая помощь будет очень оценили. Благодаря!

ответ

5

Вы не можете открыть SqlFileStream со значением NULL. Измените инструкцию INSERT, чтобы установить File = 0x, и она должна начать работать.

PS. Некоторые соображения производительности:

  1. Вы можете избежать дополнительного туда-обратно на сервер путем выдачи топка с OUTPUT clause, который возвращает контекст транзакции и путь к файлу вновь вставленного сгустка.
  2. Если вы не собираетесь читать из SqlFileStream, откройте его только для записи. В этом конкретном случае это может не быть большим делом, потому что файл, который вы открываете, пуст. Но если вы обновляете большой файл, его открытие для ReadWrite будет иметь Sql, чтобы сначала скопировать весь файл, и только тогда вы можете играть с ним.
+0

Это работало как чемпион и спасибо тонне за указатель на использование предложения, я даже не знал, что он существует. –

+0

Nice :) Работал для меня тоже – Ankit

Смежные вопросы