XPS文件太大,无法存储在数据库中

时间:2017-07-31 03:57:15

标签: c# sql-server wpf database

我正在尝试将.xps文件存储在SQL Server数据库中,但是我收到了错误

  

System.Data.SqlClient.SqlException:'字符串或二进制数据将被截断。'

我知道这意味着我要存储的数据太大了,但我也尝试过序列化文档但它仍然太大(我的数据类型为varchar(MAX)):

var xpsDocument = new XpsDocument(xpsFile, FileAccess.Read);
String toSave;

using (MemoryStream ms = new MemoryStream())
{
    var writer = new XpsSerializerFactory().CreateSerializerWriter(ms);
    writer.Write(xpsDocument.GetFixedDocumentSequence());
    toSave = Convert.ToBase64String(ms.ToArray());
}

con.Open();

SqlCommand cmd = con.CreateCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "insert into [table] values('" + filename + "', '" + toSave + "')";
cmd.ExecuteNonQuery();
con.Close();

filename只是System.IO.Path.GetFileNameWithoutExtension(openFileDialog.FileName) - 该列的数据类型为varchar(20),其长度肯定在该范围内。

还有其他方法可以进一步缩小字符串的大小吗?如果没有,是否有不同的方法将xps文件存储在数据库中?

根据msd的回答进行编辑:

byte[] toSave;

using (MemoryStream ms = new MemoryStream())
{
    var writer = new XpsSerializerFactory().CreateSerializerWriter(ms);
    writer.Write(xpsDocument.GetFixedDocumentSequence());
    toSave = ms.ToArray();
}

con.Open();

const String preparedCommand = "insert into [table] values(@FileName, @File, '', '', '', '')";

SqlCommand cmd = new SqlCommand(preparedCommand, con);
cmd.Parameters.Add("@File", SqlDbType.VarBinary).Value = toSave;
cmd.Parameters.Add("@FileName", SqlDbType.VarChar).Value = filename;

cmd.ExecuteNonQuery();
con.Close();

3 个答案:

答案 0 :(得分:2)

您必须将数据类型更改为VARBINARY(MAX)并使用以下方法将文件(作为内存流)插入数据库

public static void databaseFilePut(MemoryStream file, string fileName) 
{
   int varID = 0;
   byte[] file = fileToPut.ToArray();
   const string preparedCommand = 
              @"insert into [table] values(@FileName, @File, '', '', '', '')";
   using (var varConnection = Locale.sqlConnectOneTime(Locale.sqlDataConnectionDetails))
        using (var sqlWrite = new SqlCommand(preparedCommand, varConnection)) {
            sqlWrite.Parameters.Add("@File", SqlDbType.VarBinary, file.Length).Value = file;
            sqlWrite.Parameters.Add("@FileName", SqlDbType.VarChar, file.Length).Value = fileName;
             sqlWrite.ExecuteNonQuery();
        }
    }

编辑:使用文件流

public static void databaseFilePut(string varFilePath) {
    byte[] file;
    using (var stream = new FileStream(varFilePath, FileMode.Open, FileAccess.Read)) {
        using (var reader = new BinaryReader(stream)) {
            file = reader.ReadBytes((int) stream.Length);       
        }          
    }
    using (var varConnection = Locale.sqlConnectOneTime(Locale.sqlDataConnectionDetails))
    using (var sqlWrite = new SqlCommand("insert into [table] values(@FileName, @File, '', '', '', '')", varConnection)) {
        sqlWrite.Parameters.Add("@File", SqlDbType.VarBinary, file.Length).Value = file;
        sqlWrite.Parameters.Add("@FileName", SqlDbType.VarChar, file.Length).Value = Path.GetFileName(varFilePath);
        sqlWrite.ExecuteNonQuery();
    }
}

答案 1 :(得分:0)

使用文本翻译nvarchar(max)。你的问题会解决。

答案 2 :(得分:0)

我设法通过改变向查询添加参数的方式来解决这个问题。

 using (var sqlWrite = new SqlCommand("insert into [table] values(@FileName, @File, '" + fileSizeDisplayed + "', '" + current.ToString(dtformat) + "', 'no', 'no')", con))
    {
        SqlParameter file2 = new SqlParameter("@File", file);
        SqlParameter filename2 = new SqlParameter("@FileName", filename);
        sqlWrite.Parameters.Add(filename2);
        sqlWrite.Parameters.Add(file2);
        sqlWrite.ExecuteNonQuery();
    }