Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Базы данных под .NET > Проблема с работой Image(BLOB) и Access.


Автор: shark1 4.1.2008, 19:46
Застрял ни как не получается работать с image.
Пытаюсь добавить картинку в Access, вроде все срабатывает,а вот дальше ни как.Как например по ID вытаскивать данные и соответствующую картинку.Посмотрел весь форум и в google поискал но что то ни как.Подскажите плиззз.Код Прилагается.Зарание огромное спасибо.
Код

// **** Read Image from Filesystem and add it to the Database. 
        public void AddEmployee(
            string UserID,
            string UserName,
            string UserEmail,
            string UserDescription,
            //DateTime hireDate,
            //int preportsTo,
            string photoFilePath)
        {

            // Read Image into Byte Array from Filesystem
            byte[] photo = GetPhoto(photoFilePath);

            // Construct INSERT Command
            OleDbCommand addEmp = new OleDbCommand(
                "INSERT INTO Users ("+
                "UserID,UserName,UserEmail,UserDescription,UserPhoto) " +
                "VALUES(@UserID,@UserName,@UserEmail,@UserDescription,@UserPhoto)", conn); //@ReportsTo ReportsTo

            addEmp.Parameters.Add("@UserID", OleDbType.VarChar, 20).Value = UserID;
            addEmp.Parameters.Add("@UserName", OleDbType.VarChar, 20).Value = UserName;
            addEmp.Parameters.Add("@UserEmail", OleDbType.VarChar, 20).Value = UserEmail;
            addEmp.Parameters.Add("@UserDescription", OleDbType.VarChar, 20).Value = UserDescription;
            //addEmp.Parameters.Add("@ReportsTo", SqlDbType.Int).Value          = preportsTo;
            addEmp.Parameters.Add("@UserPhoto",     OleDbType.Binary, photo.Length).Value = photo;

            // Open the Connection and INSERT the BLOB into the Database
            conn.Open();
            addEmp.ExecuteNonQuery();
            conn.Close();
        }

        // **** Read Image into Byte Array from Filesystem
        public static byte[] GetPhoto(string filePath)
        {
            FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
            BinaryReader br = new BinaryReader(fs);

            byte[] photo = br.ReadBytes((int)fs.Length);

            br.Close();
            fs.Close();

            return photo;
        }

        // **** Read BLOB from the Database and save it on the Filesystem
        public void GetEmployee(string UserID,string UserName)
        {
            OleDbCommand getEmp = new OleDbCommand(
                "SELECT  UserPhoto " +
                "FROM Users "+
                "WHERE UserID = @UserID " +
                "AND UserName = @UserName", conn);

            getEmp.Parameters.Add("@UserID", OleDbType.VarChar, 20).Value = UserID;
            getEmp.Parameters.Add("@UserName", OleDbType.VarChar, 20).Value = UserName;

            FileStream fs;                          // Writes the BLOB to a file (*.bmp).
            BinaryWriter bw;                        // Streams the BLOB to the FileStream object.
            int bufferSize = 100;                   // Size of the BLOB buffer.
            byte[] outbyte = new byte[bufferSize];  // The BLOB byte[] buffer to be filled by GetBytes.
            long retval;                            // The bytes returned from GetBytes.
            long startIndex = 0;                    // The starting position in the BLOB output.
            string emp_id = "";                     // The employee id to use in the file name.

            // Open the connection and read data into the DataReader.
            conn.Open();
            OleDbDataReader myReader = getEmp.ExecuteReader(CommandBehavior.SequentialAccess);

            while (myReader.Read())
            {
                // Get the employee id, which must occur before getting the employee.
                emp_id = myReader.GetInt32(0).ToString();

                // Create a file to hold the output.
                fs = new FileStream("Users" + UserID + ".bmp", 
                                    FileMode.OpenOrCreate, FileAccess.Write);
                bw = new BinaryWriter(fs);

                // Reset the starting byte for the new BLOB.
                startIndex = 0;

                // Read the bytes into outbyte[] and retain the number of bytes returned.
                retval = myReader.GetBytes(1, startIndex, outbyte, 0, bufferSize);

                // Continue reading and writing while there are bytes beyond the size of the buffer.
                while (retval == bufferSize)
                {
                    bw.Write(outbyte);
                    bw.Flush();

                    // Reposition the start index to the end of the last buffer and fill the buffer.
                    startIndex += bufferSize;
                    retval = myReader.GetBytes(1, startIndex, outbyte, 0, bufferSize);
                }

                // Write the remaining buffer.
                bw.Write(outbyte, 0, (int)retval);
                bw.Flush();

                // Close the output file.
                bw.Close();
                fs.Close();
            }

            // Close the reader and the connection.
            myReader.Close();
            conn.Close();
        }

        private void btnAddEmp_Click(object sender, System.EventArgs e)
        {
            //DateTime hireDate = DateTime.Now;
            AddEmployee(textBox1.Text, textBox2.Text, textBox3.Text, textBox4.Text, _fname);//Convert.ToInt16(textBox4.Text)
            statusBar.Text = "Employee added to the Database";
            pbxPhoto.Hide();
            textBox1.Clear();
            textBox2.Clear();
            textBox3.Clear();
            textBox4.Clear();
            //textBox5.Clear();
            
        }

        private void btnGetEmp_Click(object sender, System.EventArgs e)
        {
            pbxPhoto.Show();
            GetEmployee(textBox1.Text,"");
            statusBar.Text = "Employee saved to Filesystem";
        }

        private void btnLoadPhoto_Click(object sender, System.EventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog();

            dlg.Title = "Open Photo";
            dlg.Filter = "Windows Bitmap Files (*.bmp)|*.bmp"
                + "|All files (*.*)|*.*";

            if (dlg.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    pbxPhoto.Image = new Bitmap(dlg.OpenFile());
                    _fname = dlg.FileName;
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Unable to load file: " + ex.Message);
                }
            }

            dlg.Dispose();
        }

Автор: shark1 6.1.2008, 12:07
Я конечно понимаю что код выглядет ужастно,но всетаки может кто нибудь подскажет как же всетаки сделать такое.Неужели ни кто не делал ни когда тел. книгу или список для рабочих или еще что нибудь.Подскажите плизззз,очень нужно.Зарание спасибо.

Автор: mr.DUDA 6.1.2008, 16:08
В чём проблема-то? Читаем картинку из БД в массив byte[], создаём через Image.FromStream(new MemoryStream(array)).

Автор: shark1 8.1.2008, 16:01
Уважаемый mr.DUDA  с этим делом вродебы разобрался.Теперь проблемма в следующем,значит имеется две формы.Первая главная(на ней находится dataGridView1 и прикрутил сюдаже DataBindings),вторая форма new worker(на ней имеются все текст боксы и пиктчер бокс).Вродебы все просто но вот застрял на этом.Во время когда заносятся данные в базу данных если я не указываю путь к фотографии то вылетает ошибка на этой строке :
Код

byte[] imageData = ReadFile(txtImagePath.Text);

Текст такой:System.ArgumentException: The path is not of a legal form.
Подскажите плизз как это обойти чтоб была возможность сохронять данные нового рабочего,а после можно будет добавить фото.
И еще одна проблемма.Например просто как вариант
нажимаю на кнопку захожу на форму(new worker)не чего не изменяю закрываю форму и вылетает ошибка на главной форме:
System.ArgumentException: This causes two bindings in the collection to bind to the same property.
Parameter name: binding

не понимаю откуда берется второй binding.
Подскажите плиззз,зарание огромное спасибо.

Автор: mr.DUDA 8.1.2008, 21:16
Цитата(shark1 @  8.1.2008,  15:01 Найти цитируемый пост)
The path is not of a legal form.

Судя по сообщению об ошибке, в txtImagePath нет пути к файлу или путь в некорректном формате.

Автор: shark1 9.1.2008, 13:15
Уважаемый mr.DUDA  и с этим я уже разобрался.Проблемма осталось только почему просто 
нажимаю на кнопку захожу на форму(new worker)не чего не изменяю закрываю форму и вылетает ошибка на главной форме:
System.ArgumentException: This causes two bindings in the collection to bind to the same property.
Parameter name: binding

не понимаю откуда берется второй binding.
Подскажите плиззз,зарание огромное спасибо. 

Автор: mr.DUDA 9.1.2008, 14:13
По приведённому выше коду ничего о биндингах понять нельзя. Какие контролы на что байндятся ?

Автор: shark1 9.1.2008, 15:17
Уважаемый mr.DUDA  обычные текст боксы

Код

//Get table rows from sql server to be displayed in Datagrid.
        void GetImagesFromDatabase()
        {            
            try
            {
                //Initialize SQL Server connection.
                //SqlConnection CN = new SqlConnection(txtConnectionString.Text);
                OleDbConnection conn = new OleDbConnection();//txtConnectionString.Text
                conn.ConnectionString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\Data\\Users_DB.mdb";
                //Initialize SQL adapter.
                //SqlDataAdapter ADAP = new SqlDataAdapter("Select * from ImagesStore", CN);
                OleDbDataAdapter adapter = new OleDbDataAdapter("Select * from Users", conn);

                //Initialize Dataset.
                DataSet ds = new DataSet();
                dataTable = ds.Tables.Add("Users");

                //Fill dataset with ImagesStore table.
                adapter.Fill(ds, "Users");                

                
                //Fill Grid with dataset.
                dataGridView1.DataSource = ds.Tables["Users"];
                               

                this.txt_WorkNumber.DataBindings.Add("Text", dataTable, "WorkNumber", true, DataSourceUpdateMode.OnPropertyChanged);
                this.txt_FirstName.DataBindings.Add("Text", dataTable, "FirstName", true, DataSourceUpdateMode.OnPropertyChanged);
                this.txt_LastName.DataBindings.Add("Text", dataTable, "LastName", true, DataSourceUpdateMode.OnPropertyChanged);
                this.txt_BirthDate.DataBindings.Add("Text", dataTable, "BirthDate", true, DataSourceUpdateMode.OnPropertyChanged);
                this.txt_Status.DataBindings.Add("Text", dataTable, "Status", true, DataSourceUpdateMode.OnPropertyChanged);
                this.txt_Telephone.DataBindings.Add("Text", dataTable, "Telephone", true, DataSourceUpdateMode.OnPropertyChanged);
                this.txt_Cellular.DataBindings.Add("Text", dataTable, "Cellular", true, DataSourceUpdateMode.OnPropertyChanged);
                this.txt_Address.DataBindings.Add("Text", dataTable, "Address", true, DataSourceUpdateMode.OnPropertyChanged);
                this.txt_Email.DataBindings.Add("Text", dataTable, "Email", true, DataSourceUpdateMode.OnPropertyChanged);
                this.rtb_Remarks.DataBindings.Add("Text", dataTable, "Remarks", true, DataSourceUpdateMode.OnPropertyChanged);
                this.pictureBox1.DataBindings.Add("Text", dataTable, "Photo", true, DataSourceUpdateMode.OnPropertyChanged);
               
                foreach (DataGridViewColumn column in dataGridView1.Columns) column.SortMode = DataGridViewColumnSortMode.NotSortable;               

              }
            catch(Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

Автор: mr.DUDA 10.1.2008, 11:40
Походу, если GetImagesFromDatabase() вызвать два раза, тогда добавится ещё один биндинг на каждый контрол. Не может быть такого?

Автор: shark1 13.1.2008, 09:35
Уважаемый mr.DUDA  эта функция вызывается только один раз :(,но даваыте на время это оставим,я убрал на время DataBindings.Теперь другая вылезла проблемка,есть button Delete при нажатии :

Код

try
            {
                this.adapter1.DeleteCommand.CommandText =

            "Delete * from Users where WorkNumber = " + this.txt_Find.Text;



                //open the bridge between the application and the datasource
                this.oleDbConnection.Open();

                this.adapter1.DeleteCommand.Connection = oleDbConnection;

                //execute the qurey 
                this.adapter1.DeleteCommand.ExecuteNonQuery();

                //close the connection
                this.oleDbConnection.Close();

                MessageBox.Show("Record deleted Successfully \n \nItem CLEAR !!!", "", MessageBoxButtons.OK, MessageBoxIcon.Warning);  //inform the user
                this.Close();


            }
            catch (System.Data.OleDb.OleDbException exp)
            {
                //close the connection
                this.oleDbConnection.Close();

                MessageBox.Show(exp.ToString());
            }

и вот на этом :
Код

this.adapter1.DeleteCommand.CommandText =

            "Delete * from Users where WorkNumber = " + this.txt_Find.Text;
выподает ошибка:
Код

System.NullReferenceException was unhandled
  Message="Object reference not set to an instance of an object.
,не пойму в чем дело,вроде все проверил должно сработать ночто то не то.Подскажите в чем может быть ошибка.Зарание спасибо.

Автор: tol05 13.1.2008, 13:32
Уважаемыйshark1, Вы извините, что я влезаю не в свое дело, мешаю Вашей дискуссии, но ИМХО Вы непоследовательны в своих действиях. С биндингом разбираться, так с биндингом. 

Если вываливается Exception, то у него есть замечательное свойство Exception.StackTrace, которое как раз и говорит какой метод вызвал метод, который вызвал метод, вызвавший метод, который (наконец-то!!!!) вызвал второй биндинг. Когда Вы найдете этот метод и сточку кода, вызывающую исключение, поставтьте на эту строчку брейкпоинт. Когда при отладке выполнение остановится на этой строчке, посмотрите куда делается биндинг, к какому контролу и есть ли у него уже такой биндинг. Т.о. Вы определите оба Ваших биндинга.

По поводу второй ошибки. У this.adapter1 установлена DeleteCommand? Я имею в виду есть где-нибудь код 
Код

this.adapter1.DeleteCommand = new SqlCommand();

?


Автор: thomas 13.1.2008, 13:34
shark1
Приветствую.
Сообщение говорит что, нет указания на обьект, что обьект не существует.
Попробуй показать твою команду на удаление в massagebox, сразу после 
Код

this.adapter1.DeleteCommand.CommandText =
            "Delete * from Users where WorkNumber = " + this.txt_Find.Text;

текстбокс должен быть заполнен.

Второе, если используешь конструкцию try catch то неплохо и последнюю часть использовать тоже - finally
и закрытие соединения помещать туда, а не в catch.
Код

finally
{
     //close the connection
     this.oleDbConnection.Close();
}

этот код гарантированно закроет соединение.

ЗЫ  поддерживаю tol05, команда должна быть сначала создана, а потом ей присваиваются значения.

Автор: shark1 13.1.2008, 22:06
Уважаемые tol05 и thomas ,спасибо вам за ваши замечания,постарался все исправить.Спасибо.Теперь по проблеммам.
То что касается биндинга,ошибка выподает на первой строке DataBindings.На :
this.txt_WorkNumber.DataBindings.Add("Text", dataTable, "WorkNumber", true, DataSourceUpdateMode.OnPropertyChanged);кстати сказать если я ставлю брек поинт на эту строку то даже при нажатии на  кнопку connect в коде кот.находится и this.txt_WorkNumber.DataBindings.Add и т.д сразу вылетает ошибка :( а без брек поинт все работает :( и tol05 я что то по своей молодости не нашел Exception.StackTrace.
Насчет delete .После того как я по вашей подсказке подправил код,теперь вылетает такая ошибка :Data type mismatch  in criteria expression.
Зар4ание спасибо за вашу помощ.

Автор: mr.DUDA 14.1.2008, 10:22
Модератор: Пожалуйста, один топик - один вопрос. Сначала хотя бы пробуем разобраться самостоятельно, если не получается формулируем конкретный вопрос в виде отдельной темы. Спасибо.


Автор: shark1 14.1.2008, 10:59
Уважаемый mr.DUDA  договорились.Тогда вопрос по теме DataBindings,сам старался очень но без вашей помощи ни как.Поэтому прошу помощи.Спасибо.

Автор: tol05 14.1.2008, 12:14
Цитата(shark1 @  13.1.2008,  21:06 Найти цитируемый пост)
tol05 я что то по своей молодости не нашел Exception.StackTrace


http://msdn2.microsoft.com/en-us/library/system.exception.stacktrace.aspx
а вот так это выглядит в жизни
user posted image


по поводу биндинга. Сколько раз может вызываться метод GetImagesFromDatabase()? При каждом его вызове он будет пытаться добавить новый биндинг... Нужно проверять, есть ли уже такой биндинг у контрола или нет. Если есть - то или не добавлять новый, или удалять старый.

Автор: shark1 14.1.2008, 13:47
Спасибо тебе огромное,какой я ишак,сразу нашел ошибку.Спасибо тебе.Следующий вопрос будет в новом топике,а то mr.DUDA ругается.Еще раз спасибо огромное.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)