Laden...

Dapper Implementierung für Access Inset/Update Probleme bei Strings

Erstellt von tobi45f vor 3 Jahren Letzter Beitrag vor 3 Jahren 923 Views
T
tobi45f Themenstarter:in
59 Beiträge seit 2017
vor 3 Jahren
Dapper Implementierung für Access Inset/Update Probleme bei Strings

Hallo zusammen,

bezugnehmend auf mein vorherigen Post, dessen Problem gelöst worden ist (Danke dafür 😉) habe ich mit der Umsetzung des Dappers für Access Probleme. Der Code ist prinzipiell der aus dem Tutorial.

Bei SQLite laufen alle Anweisungen, Access macht Probleme (Und leider brauche ich auch Access). Das Problem kann ich eingrenzen, bekomme es aber nicht behoben.
Connection aufbauen, Select und Delete Anweisung geht - Allerdings möchten Insert und Update nicht. Sobald ich aus der Klasse, die ich Updaten/Insert'en möchte, meine String-Member entferne, dann läuft er. Nur würde ich diese auch gern Updaten/Insert'en

Wenn ich nicht irre, dann ist der SQL Befehl für SQLite und Access doch identisch? Vor der Ausfürhung des ExecuteAsync ist der Inhalt beider Befehle identisch. 🤔

Vielen Dank, erneut! X( =)


public async Task InsertAsync(T t)
        {
            var insertQuery = GenerateInsertQuery();

            using (var connection = CreateConnection())
            {
                await connection.ExecuteAsync(insertQuery, t);
            }
        }

public async Task UpdateAsync(T t, string key)
        {
            var updateQuery = GenerateUpdateQuery(key);

            using (var connection = CreateConnection())
            {
                await connection.ExecuteAsync(updateQuery, t);
            }
        }

private string GenerateUpdateQuery(string key)
        {
            var updateQuery = new StringBuilder($"UPDATE {_tableName} SET ");
            var properties = GenerateListOfProperties(GetProperties);

            properties.ForEach(property =>
            {
                if (!property.Equals(key))
                {
                    updateQuery.Append($"{property}=@{property},");
                }
            });

            updateQuery.Remove(updateQuery.Length - 1, 1); //remove last comma
            updateQuery.Append(" WHERE "+key+"=@"+key);

            return updateQuery.ToString();
        }
private static List<string> GenerateListOfProperties(IEnumerable<PropertyInfo> listOfProperties)
        {
            return (from prop in listOfProperties
                    let attributes = prop.GetCustomAttributes(typeof(DescriptionAttribute), false)
                    where attributes.Length <= 0 || (attributes[0] as DescriptionAttribute)?.Description != "ignore"
                    select prop.Name).ToList();
        }


T
2.219 Beiträge seit 2008
vor 3 Jahren

Ohne die Fehlermeldung zu kennen, die du nicht postest, klingt es einfach nach einer Property die in der Datenbank kein entsprechendes Feld hat.
Dadurch knallt deine Anweisung, da du ein Feld updaten willst, was es so in der Access Datenbank eben nicht gibt.

Generell würde ich euch empfehlen, Access nur noch zum auslesen der Daten zu verwenden wenn nötig und die eigentlichen Operationen auf einer SQLite Datenbank zu machen.
Das spart euch einiges an Zeit und Ärger.

Auch im anderen Thread, wurde darauf schon hingewiesen, dass man für Anwendungslokale Datenbanken auf SQLite umsteigen sollte!

Nachtrag:
Da du schon dapper verwendest, solltest du deine udpate Anweisung auch nicht über Reflection o.ä. generieren lassen, dann hast du solche Probleme auch nicht.
Auch sollten SQL Anweisungen im Code am besten als const string hinterlegt werden um eben unbeabsichtig nicht irgendwelchen Unfug in die SQL Anweisungen zu schreiben.

Nachtrag 2:
Und bitte nutzt für Werte im SQL keine generierten Strings.
Nutzt dafür SQL Parameter, diese schützen dich sowohl vor SQL Inject als auch falschen SQL Anweisungen aufgrund von fehlerhaften (sprachabhängigen) Formatierungen von Datum und Dezimal Werten und vielen weiteren Problemen!
Auch muss die DB dann bei vielen gleichen Abfragen, z.B. einem Bulk Insert, nicht jede SQL anweisungen einzeln parsen, was auch ein kleiner Performance Gewinn ist!

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

16.807 Beiträge seit 2008
vor 3 Jahren

Ich hoffe Dir ist bewusst, dass Du Dich auf ein sieben(!) Jahre altes Tutorial beziehst und sich da (vor allem in Sachen Best Practise) auch - wie schon im anderen Post erwähnt - einiges geändert hat...

T
tobi45f Themenstarter:in
59 Beiträge seit 2017
vor 3 Jahren

Fehlermeldung:
Insert Objekt 1: System.Data.OleDb.OleDbException: "Datentypen in Kriterienausdruck unverträglich."
Insert Objekt 2: System.Data.OleDb.OleDbException: "Überlauf"

Beide Objekte haben dieselben Fehler wie die Tabelle der Access Datenbank. heißen auch identisch (wie gesagt, bei SQLite geht es mit denselben Namen/Aufruf bei anderer Connection)

Blöderweise kann ich die Access aber nicht ersetzen. Somit muss ich irgendwie damit klar kommen.

Ich habe die Umsetzung auch nur übernommen nach dem Tutorial 🤔

Hättest du ein Beispiel für dein Verbesserungsvorschlag zum Thema Updateanweisung?

Für die SQLParameter meinst du sowas? Dann muss ich ja jedes Feld einzeln zuweisen bei all meinen Objekten?!

also bei mir steht HIER August 2019!?

Danke!

16.807 Beiträge seit 2008
vor 3 Jahren

also bei mir steht
>
August 2019!?

Ah.. ich dachte Du meinst das YouTube Video aus 2013 mit "Tutorial". Nevermind.

Exceptions lassen sich super googlen - halt auf Englisch.
Mit Deutsch wirste kaum Treffer haben; ist nun mal so.
Daher besteht ja auch immer der allgemeine Tipp mit englischen SDKs zu entwickeln.
-> Google-Suche nach system.data.oledb.oledbexception 'data type mismatch in criteria expression

Nen Tutorial ist ja meist nur eine Basis (wie hier).
Ein Tutorial muss man jedoch auch verstehen - und Anwenden können.
Aus verschiedenen Tutorials sich Zeug zusammen puzzlen hilft ja beim Verständnis und der Anwendung meist wenig.

Die Kritikpunkte zum Code hab zumindest ich ja im alten Thema schon genannt.