Laden...

Firebird + Reflection: Das Objekt stimmt mit dem Zieltyp nicht überein

Erstellt von bi0s vor 11 Jahren Letzter Beitrag vor 11 Jahren 3.835 Views
B
bi0s Themenstarter:in
5 Beiträge seit 2008
vor 11 Jahren
Firebird + Reflection: Das Objekt stimmt mit dem Zieltyp nicht überein

Hallo zusammen,

ich sitze seit Tagen an einer WinForms Applikation die Dateien in eine FireBird Datenbank schreiben soll. Die FireBird.Client.dll habe ich per Resource eingebunden und rufe über Reflection die Connection etc auf. Ein simples Insert ohne Parameter oder ein Update funktionieren bereits einwandfrei! Doch jetzt mein großes Problem, ich muss objekte (Dateien, Bilder etc.) nun per Insert einspielen und dafür müssen in Firebird Parameter verwendet werden. Ich bekomme es per Reflection aber überhaupt nicht gebacken und bin gerade mehr als am verzweifeln.. Vieleicht hat da jemand einen Ansatz für mich..

Hier mal mein Code bzw. die wichtigen Stellen:



private static Assembly LoadAssembly(string assemblyName)
        {
            byte[] bytes;

            using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("ProjektName." + assemblyName))
            {
                bytes = new byte[(int)stream.Length];
                stream.Read(bytes, 0, bytes.Length);
            }

            return Assembly.Load(bytes);
        }


public static void InitialisiereDB()
{
ConnectionString = "User=" + DBUser + ";Password=" + DBPass + ";Database=" + DBPath + ";DataSource=" + DBIP + ";Dialect=3;Charset=WIN1252;";

            asm = LoadAssembly("FirebirdSql.Data.FirebirdClient.dll");
            mytyp = asm.GetType("FirebirdSql.Data.FirebirdClient.FbConnection", true, true);
            obj = Activator.CreateInstance(mytyp);

            miCS = mytyp.GetMethod("set_ConnectionString");
            miOpen = mytyp.GetMethod("Open");

            resCS = miCS.Invoke(obj, new object[] { ConnectionString });
            resOpen = miOpen.Invoke(obj, null);
}

public static void NonQuerySQL(string SQLString)
        {
            MethodInfo miTrans = mytyp.GetMethod("BeginTransaction", new Type[] { });
            Object resTrans = miTrans.Invoke(obj, null);

            Object[] para = new Object[3];
            para[0] = SQLString;
            para[1] = obj;
            para[2] = resTrans;

            Type mytypSQL = asm.GetType("FirebirdSql.Data.FirebirdClient.FbCommand", true, true);
            Object objSQL = Activator.CreateInstance(mytypSQL, para);

            if (objSQL != null)
            {
                Object resSQL1 = mytypSQL.GetMethod("ExecuteNonQuery", new Type[] { }).Invoke(objSQL, null);
                Object myTranstype = resTrans.GetType().GetMethod("Commit", new Type[] { }).Invoke(resTrans, null);
            }
        }


public static void Insert(string FileName, object FileObject)
        {
            MethodInfo miTrans = mytyp.GetMethod("BeginTransaction", new Type[] { });
            Object resTrans = miTrans.Invoke(obj, null);

            Object[] para = new Object[3];
            para[0] = "INSERT INTO TABELLE (ID, PFAD, NAME, DATEI) VALUES (323232, 'test', 'rofl', @Datei)";
            para[1] = obj;
            para[2] = resTrans;

            Type mytypSQL = asm.GetType("FirebirdSql.Data.FirebirdClient.FbCommand", true, true);
            Object objSQL = Activator.CreateInstance(mytypSQL, para);


            Object CPara = mytypSQL.GetMethod("CreateParameter", new Type[] { }).Invoke(objSQL, null);

            Object[] par = new Object[2];
            par[0] = "@Datei";
            par[1] = FileObject;

            Type mytypDR = CPara.GetType();
            Object fbPara = Activator.CreateInstance(mytypDR, par);

            PropertyInfo[] props = mytypSQL.GetProperties();

            foreach (PropertyInfo pi in props)
            {
                if (pi.PropertyType.FullName == "FirebirdSql.Data.FirebirdClient.FbParameterCollection")
                {
                    Type FbParaColType = pi.PropertyType;
                    MethodInfo Add = FbParaColType.GetMethod("Add", new Type[] { typeof(object) });
                    Object resRead = Add.Invoke(FbParaColType, new Object[] { par });
                }
            }


            if (objSQL != null)
            {
                Object resSQL1 = mytypSQL.GetMethod("ExecuteNonQuery", new Type[] { }).Invoke(objSQL, null);
                Object myTranstype = resTrans.GetType().GetMethod("Commit", new Type[] { }).Invoke(resTrans, null);
            }
        }


Das NonQuery funktioniert einwandfrei. Beim Insert erhalte ich folgende Exception:
"Das Objekt stimmt mit dem Zieltyp nicht überein."

Ich bin echt am verzweifeln..
Vielen Dank vorab!

Grüße, Patrick

P.s.: .Net Framwork 4.0, VS 2010, FirebirdSql.Data.FirebirdClient.dll 2.6.5

2.187 Beiträge seit 2005
vor 11 Jahren

Hallo bi0s,

warum verwendest du Reflection um die FireBird-DLL zu benutzen?
Du könntest eigentlich ganz normal die Typen verwenden. ???

Gruß
Juy Juka

B
bi0s Themenstarter:in
5 Beiträge seit 2008
vor 11 Jahren

Hallo,

ich möchte die DLL direkt in die EXE einbinden da die EXE Teil eines anderen Programmes seien wird, das wiederrum auch die Firebird.dll verwendet, jedoch meistens in einer anderen Version. Sprich ich möchte die Firebird.dll nicht als externe DLL haben sondern direkt in meine EXE integrieren um auf die Datenbank zugreifen zu können ohne externe Hilfsmittel oder zu hoffen das die Firebird.dll in der richtigen Version vorhanden ist.

Gruß, Patrick

F
10.010 Beiträge seit 2004
vor 11 Jahren

Das ist kein Grund sich so in den Fuss zu schiessen.

Wie man vernünftig die DLL integriert haben wir hier im Forum zig male beschrieben, und deine Version ist in keiner vorgekommen.

B
bi0s Themenstarter:in
5 Beiträge seit 2008
vor 11 Jahren

Sorry aber deinen Satz verstehe ich nicht 😉

Was wäre denn deiner Meinung nach der richtige Weg?

D
615 Beiträge seit 2009
vor 11 Jahren

Haööp bi0s

Er meinte das du die DLL ganz normal als Referenz hinzufügen sollst.

ich möchte die DLL direkt in die EXE einbinden da die EXE Teil eines anderen Programmes seien wird, das wiederrum auch die Firebird.dll verwendet,

Ich versteh zwar nicht warum du die DLL in die EXE (was auch ne DLL ist) einbinden willst, aber das geht mit IL MERGE.

Wenn 2 Projekte die selbe Assembly referenzieren, hast du diese danach nur 1 Mal beim publishen, insofern es wirklich die selbe Assembly ist (Version ...).

(alles andere macht ja auch wenig Sinn)

Beste Grüsse

Diräkt

B
bi0s Themenstarter:in
5 Beiträge seit 2008
vor 11 Jahren

ILMerge sieht ja auf den ersten Blick schonmal sehr gut aus...
Das würde mich ne menge Arbeit abnehmen!

Scheinbar funktioniert es damit wunderbar 😉
Werde es übers Wochenende mal richtig durchtesten.

Der Tipp ist aufjedenfall Gold wert!
Vielen Dank 😉