davin

Just a little thinking and interest!

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

   忙了好长一阵子,silvelight项目总算告一段落了,在这个项目中,使用了sqlserver 2008,当然是觊觎它的新特性fileStream和hierarchyid.因此在最开始,没少去查阅msdn和做一些练习,所以元旦长假就打算做一个比较完整的练习,从安装sqlserver2008开始,在msdn的帮助下一步一步来完成.下面是完成fileStream练习的步骤:

1.SQL Server2008 enabled fileStream

  因为我在安装sql server 2008的时候,在配置filestream的时候就已经将sql server2008的选项打勾了。当然如果安装的时候没有选择enabled fileStream,可以在

sql server configuration manager(配置管理器)如图,或者在查询分析器里面执行下面的sql 语句

EXEC sp_configure filestream_access_level, 2 RECONFIGURE ;filestream_access_level 的值 详细参考msdn

 

2.Database enabled fileStream 

 下面是我的data base script,显然这里和一般的数据库多了一个'Group'(fileStream Data类型)

CREATE DATABASE [fileStreamTest] ON  PRIMARY
( NAME = N'fileStreamTest', FILENAME = N'C:\data\fileStreamTest.mdf' , SIZE = 3072KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB ),
 FILEGROUP [fileStreamGroup1] CONTAINS FILESTREAM  DEFAULT
( NAME = N'fileStreamGroup', FILENAME = N'C:\data\fileStreamGroup' )
 LOG ON
( NAME = N'fileStreamTest_log', FILENAME = N'C:\data\fileStreamTest_log.ldf' , SIZE = 1024KB , MAXSIZE = 1GB , FILEGROWTH = 10%)
GO

注意的地方是c:\Data 目录必须存在,而filestream1'子目录在c:\Data则不能已存在

执行完毕查看c:\Data目录下面有fileStream1目录,打开发现有 有一个filestream.hdr f文件和一个名为 $FSLOG 的字文件夹.

3.Table enabled FileStream

在这里问题就来了(问题先不说),我按照 How to: Create a Table for Storing FILESTREAM Data这里讲的新建Records,脚本如下,按照msdn说明,Id列是一个ROWGUIDCOL列,Chart 作为文件存储的列不仅是VARBINARY(MAX)类型 ,同时还需要赋予一个fileStream特性.

CREATE TABLE .dbo.Records 

(

    [Id] [uniqueidentifier] ROWGUIDCOL NOT NULL UNIQUE, 

    [SerialNumber] INTEGER UNIQUE,

    [Chart] VARBINARY(MAX) FILESTREAM NULL

)

4.通过ado.net来访问fileStream,我参考项目中用到的方法写了这个方法

put
 1  static void put(string fileName)
 2         {
 3             SqlConnection conn = null;
 4             SqlTransaction tran = null;
 5             SqlCommand cmd = null;        
 6             try
 7             {
 8                 //get file content
 9                 FileStream input = new FileStream(fileName, FileMode.Open, FileAccess.Read);
10                 byte[] buffer = new byte[(int)input.Length];
11                 input.Read(buffer, 0, buffer.Length);
12 
13                 conn = GetConnection();
14                 tran = conn.BeginTransaction();
15                 //call proc
16                 cmd = new SqlCommand("putFileStream", conn, tran);//add a new record ,but filestream is null,return filestream.PathName
17                 cmd.CommandType = System.Data.CommandType.StoredProcedure;
18                 cmd.Parameters.Add(new SqlParameter("@serialNumber"new Random().Next(1000)));             
19                 SqlDataReader r = cmd.ExecuteReader(System.Data.CommandBehavior.SingleRow);
20                 r.Read();
21                 string id = r[0].ToString();
22                 string path = r[1].ToString();
23                 r.Close();
24 
25                 // get the transaction context
26                 SqlCommand command = new SqlCommand(@"select Chart.PathName(),GET_FILESTREAM_TRANSACTION_CONTEXT() from Records where id=@id", conn, tran);
27                 command.Parameters.AddWithValue("@id", id);
28                 // open a Filestream to write the blob
29                 SqlDataReader reader;
30                 reader = command.ExecuteReader(CommandBehavior.SingleRow);
31                 reader.Read();
32                 SqlString sqlFilePath = reader.GetSqlString(0);
33                 SqlBinary transactionToken = reader.GetSqlBinary(1);
34 
35                 reader.Close();
36 
37                 if (transactionToken.Length != 0)
38                 {
39                     //open a sqlfileStream
40                     SqlFileStream stream = new SqlFileStream(sqlFilePath.Value, transactionToken.Value, FileAccess.Write, FileOptions.SequentialScan, 0);
41                     //write file to sqlfilestream
42                     stream.Write(buffer, 0, buffer.Length);
43                     stream.Close();
44                 }
45                 tran.Commit();
46                 conn.Close();
47             }
48             catch
49             {
50 
51             }
52         }

 

 我开始调用put方法,可结果数据库没有记录,这让我很好奇,我开启了sql profile并同时开始debug,发现都正常,可结果数据库没有记录,我把sqlprofile抓到的

sql exec putFileStream @serialNumber=555,拿到分析器查询,没有问题,不过当我用sql加入了一条记录之后,在用程序调用put方法结果就正常了,不知道什么原因总之郁闷了几个小时。

下面也贴一下读取fileStream的代码 

get
1 public byte[] getFileStream(Guid id)
 
2         {
 
3             SqlConnection conn = null;
 
4             SqlTransaction tran = null;
 
5             SqlCommand cmd = null;
 
6             byte[] bytes = null;// getFileStream
 7             conn = GetConnection();
 
8             tran = conn.BeginTransaction();
 
9 
10             cmd = new SqlCommand("SELECT [Chart].PathName(), GET_FILESTREAM_TRANSACTION_CONTEXT() FROM [Records] WHERE [id] = @id;", conn, tran);
11             //cmd.CommandType = System.Data.CommandType.StoredProcedure;
12             cmd.Parameters.Add("@id", SqlDbType.UniqueIdentifier).Value = id;
13 
14             SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.SingleRow);
15             if (rdr.Read())
16             {
17                 SqlString sqlFilePath = rdr.GetSqlString(0);
18                 SqlBinary transactionToken = rdr.GetSqlBinary(1);
19                 rdr.Close();
20 
21                 SqlFileStream fileStream = new SqlFileStream(sqlFilePath.Value, transactionToken.Value, FileAccess.Read);
22                 bytes = new byte[fileStream.Length];
23                 fileStream.Read(bytes, 0, bytes.Length);
24                 fileStream.Close();//if fileStream have not close,tran.Commit throw process error
25                 tran.Commit();
26             }
27             conn.Close();
28             return bytes;
29         }
30 
31 

 

 

 参考文档http://technet.microsoft.com/en-us/library/cc645923.aspx

 

 

 

posted on 2010-01-04 23:18  davin  阅读(926)  评论(0编辑  收藏  举报