Преобразовать массив byte [] в DataTable - PullRequest
4 голосов
/ 19 августа 2009

Я сохранил объект типа DataTable в базе данных SQL 2005 в поле типа varbinary. Я хочу получить его обратно, но я не смог набрать его. Вот как я его сохранил.

MemoryStream memStream = new MemoryStream();
    StreamWriter sw = new StreamWriter(memStream);

sw.Write(dt);
con.Open();
using (SqlCommand cmd = new SqlCommand("INSERT INTO Tables(TableName, TableData, QuestionID) VALUES (@TableName, @TableData, @QuestionID)", con))
{
    cmd.Parameters.Add("@TableName", SqlDbType.VarChar).Value = "a new table";
    cmd.Parameters.Add("@TableData", SqlDbType.VarBinary,Int32.MaxValue).Value = memStream.GetBuffer();
    cmd.Parameters.Add("@QuestionID", SqlDbType.VarChar).Value = "2";
    cmd.ExecuteNonQuery();

}

'dt' - это экземпляр объекта DataTable.

Ответы [ 4 ]

6 голосов
/ 19 августа 2009

То, о чем вы говорите, - это двоичная сериализация и десериализация. Возможно это поможет.

using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Data;
using System.Text;

namespace Serial
{
    public class Ser
    {
        public static byte[] StrToByteArray(string str)
        {
            UTF8Encoding  encoding = new UTF8Encoding ();
            return encoding.GetBytes(str);
        }

        public static string ByteArrayToStr(byte[] barr)
        {
            UTF8Encoding  encoding = new UTF8Encoding ();
            return encoding.GetString(barr, 0, barr.Length);
        }

        public static void Main(String[] args)
        {
            DataTable dt = new DataTable();
            DataRow dr;

            dt.Columns.Add(new DataColumn("IntegerValue", typeof(Int32)));
            dt.Columns.Add(new DataColumn("StringValue", typeof(string)));
            dt.Columns.Add(new DataColumn("DateTimeValue", typeof(DateTime)));
            dt.Columns.Add(new DataColumn("BooleanValue", typeof(bool)));

            for (int i = 1; i <= 1; i++) 
            {

                dr = dt.NewRow();

                dr[0] = i;
                dr[1] = "Item " + i.ToString();
                dr[2] = DateTime.Now;
                dr[3] = (i % 2 != 0) ? true : false;

                dt.Rows.Add(dr);
            }

            //Serialize
            BinaryFormatter bformatter = new BinaryFormatter();
            MemoryStream  stream = new MemoryStream();

            string s;
            bformatter.Serialize(stream, dt);
            byte[] b = stream.ToArray();
            s = ByteArrayToStr(b);
            stream.Close();
            dt = null;

            //Now deserialise
            bformatter = new BinaryFormatter();
            byte[] d;
            d = StrToByteArray(s);
            stream = new MemoryStream(d);
            dt = (DataTable)bformatter.Deserialize(stream);
            stream.Close();
        }
    }
}
1 голос
/ 19 августа 2009

Боюсь, мне придется вас разочаровать, по крайней мере, пока вы не скажете нам, что создали метод расширения для класса StreamWriter, который обрабатывает таблицы данных.

Единственной перегрузкой метода Write, который принимает экземпляр DataTable, является тот, который принимает объект, и согласно документации MSDN он сохраняет только «текстовое представление» объекта.

Итак, будем надеяться, что метод .ToString объекта DataTable выводит строку в формате, который содержит все содержимое экземпляра DataTable, но, увы. Только метод .ToString возвращает содержимое свойства TableName и отображаемое выражение, если оно есть.

Итак, вы сохранили не все содержимое экземпляра DataTable, а только имя таблицы.

Вы должны изучить Сериализация , она должна быть в состоянии создать двоичное или XML-представление всего содержимого объекта DataTable.

0 голосов
/ 19 августа 2009

Возможно, лучше использовать XmlSerializer или BinaryFormatter для сериализации вашей таблицы данных, а затем сохранить ее в двоичном столбце.

Ссылки для этого:
http://sadeveloper.net/forums/p/439/1772.aspx
http://bytes.com/topic/net/answers/428472-serializing-datatable

0 голосов
/ 19 августа 2009

Я предполагаю, что ваш код только что сериализовал таблицу данных, и вы должны десериализовать ее. Я не знаю, какой форматтер использовался, поэтому вам придется посмотреть содержимое вашего двоичного поля. Если это двоичный файл, используйте BinaryFormater (см. Пример кода внизу страницы). Если это не двоичный файл, попробуйте SoapFormatter и XmlSerializer .

...