Entwickler-Ecke

Datenbanken (inkl. ADO.NET) - Image aus Datenbank auslesen SQL CE (Compact) klappt nicht!


Marc Dirk - Do 12.09.13 17:05
Titel: Image aus Datenbank auslesen SQL CE (Compact) klappt nicht!
Hallo Ihr Lieben!

ich versuch schon seit 2 Tagen hinter das Problem zu kommen. Ich habe nun das "ganze" Internet rauf und runter abgesucht und verstehe einfach nicht was ich falsch mache. Ich habe in meine Tabelle Bilder als Byte[]-Objekte abgelegt. Die SQL Compact 4.0 Toolbox liefert mir auf meine SELECT Anweisung auch ein System.Byte[] zurück. Soweit so gut.

Mit meiner unten beschriebenen Funktion bekomme ich statt des Image leider nur diesen Fehler zurück:

System.IndexOutOfRangeException: Aufgabenkontext
bei System.Data.SqlServerCe.FieldNameLookup.GetOrdinal(String fieldName)
bei System.Data.SqlServerCe.SqlCeDataReader.GetOrdinal(String name)
bei System.Data.SqlServerCe.SqlCeDataReader.get_Item(String name)


Ich schätze es ist nur eine Kleinigkeit, aber ich komme nicht dahinter :autsch:

Please, help me!!!!!!!!!



C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
public static Image func_read_images_from_database( string string_ConnectionString, string ID_Dokumente, string SearchColumn )
        {
          Image img;
          byte[] imgData = null;

            using (SqlCeConnection con = new SqlCeConnection(string_ConnectionString))
            {
              con.Open();
                using (SqlCeCommand com = new SqlCeCommand("SELECT '" + SearchColumn + "' FROM Dokumente WHERE ID_Dokumente = '" + ID_Dokumente + "'", con)) 
                {
                    try
                    {
                        using (SqlCeDataReader dr = com.ExecuteReader())
                        {
                            while (dr.Read())
                            {
                                imgData = (byte[]) dr[SearchColumn];
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.ToString());
                    }
                    finally
                    {
                        con.Close();
                    }
              }
          }
   
      if (imgData != null) {
          //Es wurde ein Bild geladen
          MemoryStream ms = new MemoryStream(imgData);
          img = Image.FromStream(ms);
          return img;
      }
      return null;
}


Th69 - Do 12.09.13 19:29

Hallo Marc Dirk,

anscheinend kann die SearchColumn nicht aufgelöst werden. Versuche entweder mal dr[0] oder aber entferne mal die Anführungsstriche bei deinem SELECT um den Spaltennamen herum.

P.S. Statt dem Hantieren mit den Anführungsstrichen bei der ID solltest du besser SQL-Parameter benutzen.


Marc Dirk - Do 12.09.13 20:09

user profile iconTh69 hat folgendes geschrieben Zum zitierten Posting springen:
Hallo Marc Dirk,

anscheinend kann die SearchColumn nicht aufgelöst werden. Versuche entweder mal dr[0] oder aber entferne mal die Anführungsstriche bei deinem SELECT um den Spaltennamen herum.


Wenn ich es "fest verdrahte" -> imgData = (byte[]) sqlReader["Aufgabenkontext"];
kommt das selbe dabei raus.


user profile iconTh69 hat folgendes geschrieben Zum zitierten Posting springen:

P.S. Statt dem Hantieren mit den Anführungsstrichen bei der ID solltest du besser SQL-Parameter benutzen.

Wie meinst Du das?


Ralf Jansen - Do 12.09.13 20:21

In der SELECT Clause hast du den Spaltennamen gequotet. Heißt wenn in SearchColumn 'Aufgabenkontext' steht hast du


SQL-Anweisung
1:
SELECT 'Aufgabenkontext' FROM Dokumente WHERE ID_Dokumente = 'MeineLiebeID'                    


an die Datenbank geschickt. Wird vermutlich von CE so interpretiert das du in der ersten Spalte immer den string "Aufgabenkontext" zurückbekommst ohne Spaltennamen da du keinen Spaltennamen angegeben hast sondern ein fixes Literal. Also lass die Single Quotes um Aufgabenkontext weg.


Marc Dirk - Do 12.09.13 22:10

user profile iconRalf Jansen hat folgendes geschrieben Zum zitierten Posting springen:
In der SELECT Clause hast du den Spaltennamen gequotet. Heißt wenn in SearchColumn 'Aufgabenkontext' steht hast du


SQL-Anweisung
1:
SELECT 'Aufgabenkontext' FROM Dokumente WHERE ID_Dokumente = 'MeineLiebeID'                    


an die Datenbank geschickt. Wird vermutlich von CE so interpretiert das du in der ersten Spalte immer den string "Aufgabenkontext" zurückbekommst ohne Spaltennamen da du keinen Spaltennamen angegeben hast sondern ein fixes Literal. Also lass die Single Quotes um Aufgabenkontext weg.



Meine Güte, Du hast Recht! Ich wusste doch, es sind die Kleinigkeiten im Leben über die wir stolpern!
Vielen, vielen Dank!


Th69 - Fr 13.09.13 09:31

Hallo again,

mit SQL-Parameter meine ich die Benutzung der Klasse SqlParameterCollection durch die SqlCommand.Parameters-Eigenschaft, s. z.B. C# SqlParameter [http://www.dotnetperls.com/sqlparameter] oder [Artikelserie] SQL: Parameter von Befehlen [http://www.mycsharp.de/wbb2/thread.php?threadid=66704]. Dort werden auch die Nachteile deiner bisherigen String-Konkatenation (mit den Anführungsstrichen) genannt. ;-)

Das einzige, was du ausprobieren mußt, ist, ob man "@Name" oder ":Name" oder "?Name" bei SqlServerCe schreiben muß.


Ralf Jansen - Fr 13.09.13 12:52

ID_Dokumente kann man sicher (und sollte man auch) durch einen Parameter ersetzen. Bei SearchColumn aber wohl eher nicht möglich. Zumindest wäre dann Ce die erste Datenbank die ich kenne wo man DBObjekte durch Parameter ersetzen könnte und nicht nur ausschließlich Werte.