Как хранить и извлекать файлы DICOM в SQL Server с помощью C#

Моя цель - хранить файлы DICOM в SQL Server с некоторым идентификатором, и когда пользователю нужен этот файл DICOM, он может загрузить его с SQL Server, используя соответствующий идентификатор. Файл не должен изменять свою оригинальность при сохранении на сервере, а также при извлечении из SQL Server. Я использую тип данных Varbinary(max) для хранения массива байтов файла DICOM в SQL Server. Я преобразовываю поток памяти файла DICOM в массив байтов, а затем сохраняю на сервере SQL, как указано ниже:

 using (MemoryStream memStream = new MemoryStream())
 {
    using (FileStream fileStream = File.Open(txtDICOMFilePath.Text, FileMode.Open))
    {
         // Copy the file stream to memory stream.
         fileStream.CopyTo(memStream);
    }
    int intL = Convert.ToInt32(memStream.Length);
    byte[] objData = new byte[intL];
 }

 //Set insert query
 string qry = "insert into ImagesStore (ID,ImageData) values(@ID, @ImageData)";

 //Initialize SqlCommand object for insert.
 SqlCommand SqlCom = new SqlCommand(qry, CN);

 //We are passing Original Image Path and Image byte data as sql parameters.
 SqlCom.Parameters.Add(new SqlParameter("@ID", (object)txtUniqueID.Text));
 SqlCom.Parameters.Add(new SqlParameter("@ImageData", (object)objData));

 //Open connection and execute insert query.
 CN.Open();
 SqlCom.ExecuteNonQuery();
 CN.Close();

Проблема. При сохранении изображения оно сохраняется правильно (без каких-либо исключений), но при извлечении не дает точных данных. Может ли кто-нибудь помочь мне сохранить файл DICOM на сервере SQL без каких-либо потерь?

Обновление: Ниже приведен мой код для загрузки файла DICOM.

qry = "select ImageData from ImagesStore where ID= @ID";

 //Initialize SqlCommand object for insert.
 SqlCom = new SqlCommand(qry, CN);

 SqlCom.Parameters.Add("@ID", SqlDbType.Int).Value = (object)txtUniqueID.Text;

 SqlDataAdapter adp = new SqlDataAdapter(SqlCom);

 DataTable dt = new DataTable();

 try
 {

     if (CN.State == ConnectionState.Closed)
        CN.Open();

     adp.Fill(dt);

     if (dt.Rows.Count > 0)
     {

           MemoryStream ms = new MemoryStream((byte[])dt.Rows[0]["ImageData"]);

           //Logic to save the file
     }
 }
 catch (Exception ex)
 {
     MessageBox.Show(ex.Message, "Error",MessageBoxButtons.OK, MessageBoxIcon.Error);
 }

person SharpUrBrain    schedule 31.07.2012    source источник
comment
Сообщение, которое вы загружаете. Например, что теряется?   -  person paparazzo    schedule 31.07.2012
comment
весь файл DICOM становится нечитаемым после загрузки с SQLServer и сохранения на локальном компьютере.   -  person SharpUrBrain    schedule 31.07.2012
comment
Возможно, я ошибаюсь при загрузке файла с сервера SQL, не могли бы вы помочь мне, как загрузить и сохранить файл на локальный компьютер с помощью С#.   -  person SharpUrBrain    schedule 31.07.2012
comment
Вы утверждаете, что код не работает. Опубликуйте свой код загрузки, который не работает.   -  person paparazzo    schedule 01.08.2012
comment
@Blam, я обновил свой вопрос.   -  person SharpUrBrain    schedule 01.08.2012
comment
У вас есть что-нибудь в мс? И вы должны иметь возможность использовать .ExecuteScalar() для обхода datatable и dataadapter.   -  person paparazzo    schedule 01.08.2012
comment
Этот образец должен быть byte[] codeproject.com/Articles/225446/   -  person paparazzo    schedule 01.08.2012


Ответы (1)


Объявите byte[] objData снаружи и перед использованием блока и попробуйте установить размер байтового массива:

byte []objData=null;
using (MemoryStream memStream = new MemoryStream())
 {
    using (FileStream fileStream = File.Open(txtDICOMFilePath.Text, FileMode.Open))
    {
         fileStream.CopyTo(memStream);
    }
    int intL = Convert.ToInt32(memStream.Length);
    objData = new byte[intL];
    memStream.Read(objData,0,objData.Length);
 }

SqlCom.Parameters.Add("@ImageData",SqlDb.Image,objData.Length).Value=objData;

РЕДАКТИРОВАТЬ: Чтобы прочитать данные из ImagesStore

string qry = "select * From ImagesStore";

using(SqlConnection Cn=new SqlConnect(CnStr))
{
  using(SqlCommand SqlCom = new SqlCommand(qry, CN))
  {
    Cn.Open();
    using(SqlDataReader dr=SqlCom.ExecuteReader())
    {
      while(dr.Read())
      {
          string path="x:\\folder\\" + dr[0] + ".png";
          byte []bytes=(byte[])dr[1];
          System.IO.File.WriteAllBytes(path,bytes);
       }
    }
  }
}

В качестве альтернативы вы можете использовать DataAdapter/DataTable (код в OP)

if (dt.Rows.Count > 0)
     {
        foreach(DataRow row in dt.Rows)
         {
          string path="x:\\folder\\" + row[0] + ".png";
          byte []bytes=(byte[])row[1];
          System.IO.File.WriteAllBytes(path,bytes);
         }
     }
person kv-prajapati    schedule 31.07.2012
comment
Не могли бы вы рассказать мне, как получить данные с SQL Server и сохранить их на локальной машине? - person SharpUrBrain; 31.07.2012
comment
Используйте System.IO.FileStream для сохранения/записи массива байтов в файл на диске. - person kv-prajapati; 01.08.2012