Laden...

SQLite & EntityFramework 6 - Wie bekomme ich die Auswahl "SQLite" in der Dropdown "New Connection"?

Erstellt von resper vor 6 Jahren Letzter Beitrag vor 6 Jahren 2.465 Views
R
resper Themenstarter:in
33 Beiträge seit 2017
vor 6 Jahren
SQLite & EntityFramework 6 - Wie bekomme ich die Auswahl "SQLite" in der Dropdown "New Connection"?

Hallo,

ich versuche gerade EntityFramework 6 mit SQLite in meiner App zum Laufen zu bringen.

Ich habe dieses Tutorial als Grundlage genommen:

https://erazerbrecht.wordpress.com/2015/06/11/sqlite-entityframework-6-tutorial/

Ich bekomme aber einfach nicht bei New Connection SQLite zur Auswahl.

Ich habe die NuGetPakete installiert:

EntityFramework 6.1.3
System.Data.SQLite 1.0.105.1
System.Data.SQLite.Core 1.0.105.1
System.Data.SQLite.EF6 1.0.105.1
System.Data.SQLite.Linq 1.0.105.1

Ich habe das Paket von SQL herunter geladen:

sqlite-netFx451-setup-bundle-x86-2013-1.0.105.1.exe

und das Target Frameworka auf 4.5.1 gesetzt.

Ich weiß leider nicht, was ich übersehe.

16.842 Beiträge seit 2008
vor 6 Jahren

Der Wizard gibt es in der identischen Form auch in neuen VS Versionen nicht mehr.
Es hat sich deutlich herausgestellt, dass die Umsetzung direkt im Code - Code First - viel effizienter ist.
Der Wizard legt eh nur den Connection String in der *.config an; arg viel mehr macht er nicht.

R
resper Themenstarter:in
33 Beiträge seit 2017
vor 6 Jahren

Ok. Leider sind die meisten ausführlichen Tutorials und Code Schnipsel, die ich im Netzt zum Thema WPF und SQLite gefunden habe in Zusammenhang mit dem EntityFramework 6.

Momentan habe ich meine SQLite Operationen in einer Helfer Klasse, aber irgendwie sieht das ganze für mich "unelegant" aus.

In meinem MainViewModel nutze ich das ganze so (Beispiele):

SQLiteHelper sqlite = new SQLiteHelper();

if (!sqlite.CheckAdmin())
{
[...]
}
User login = sqlite.Login(Loginname, HelperClass.MD5Hash(Password));

Und mein SQLite Klasse sieht so aus:

    class SQLiteHelper
    {
        private SQLiteConnection sqlConn;
        private static string sqliteFile = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "/resperLaMe.db";  // set folder for database
        private static string sqlitePw = "dbpassword"; // set password for database

        public SQLiteHelper()
        {
            // check if database file exist when not create with password
            if (!File.Exists(sqliteFile))
            {
                sqlConn = new SQLiteConnection("Data Source=" + sqliteFile);
                sqlConn.SetPassword(sqlitePw);
            }
            sqlConn = new SQLiteConnection("Data Source=" + sqliteFile + ";Password=" + sqlitePw); // connect to database

            // create tables, when not exist
            string query =
                "CREATE TABLE IF NOT EXISTS user (id INTEGER PRIMARY KEY AUTOINCREMENT, 'login' TEXT, 'firstname' TEXT, 'lastname' TEXT, 'persid' TEXT, 'password' Text, 'role' INTEGER, 'first' INTEGER, 'active' INTEGER);" +
                "CREATE TABLE IF NOT EXISTS userRights (id INTEGER PRIMARY KEY, 'lwe' INTEGER, 'lwa' INTEGER, 'lwb' INTEGER, 'lwi' INTEGER, 'mwe' INTEGER, 'mwa' INTEGER, 'mwb' INTEGER, 'mwi' INTEGER, 'vacc' INTEGER, 'vadr' INTEGER);" +
                "CREATE TABLE IF NOT EXISTS admin ('password' Text);";
            queryNon(query);
        }


        // check if admin password exist
        public bool CheckAdmin()
        {
            sqlConn.Open();
            var command = sqlConn.CreateCommand();
            command.CommandText = "SELECT * FROM admin";
            SQLiteDataReader reader = command.ExecuteReader();
            bool rows = reader.HasRows;
            sqlConn.Close();
            return rows;
        }

        // login user
        // if login doesnt match return an empty user
        public User Login(string login, string pw)
        {
            User user = new User();

            sqlConn.Open();

            if (!login.Equals("Admin"))
            {
                var command = sqlConn.CreateCommand();
                command.CommandText = "SELECT * FROM user LEFT JOIN userRights ON user.id = userRights.id WHERE user.login = '@login' AND user.password = '@password';";
                command.Parameters.AddWithValue("@login", login);
                command.Parameters.AddWithValue("@password", pw);
                SQLiteDataReader reader = command.ExecuteReader();
                if (reader.HasRows)
                {
                    while (reader.Read())
                    {
                        user.Id = reader.GetInt32(0);
                        user.Login = reader.GetString(1);
                        user.Role = reader.GetInt16(6);
                        break;
                    }
                }
            }
            else
            {
                var command = sqlConn.CreateCommand();
                command.CommandText = "SELECT * FROM admin WHERE admin.password = '@password'";
                command.Parameters.AddWithValue("@password", pw);
                SQLiteDataReader reader = command.ExecuteReader();
                if (reader.HasRows)
                {
                    user.Id = 0;
                    user.Login = "Admin";
                    user.Role = -1;
                }
            }

            sqlConn.Close();

            return user;
        }

        // methode for querys without response
        private void queryNon(string query)
        {
            sqlConn.Open();
            var command = sqlConn.CreateCommand();
            command.CommandText = query;
            command.ExecuteNonQuery();
            sqlConn.Close();
        }
    }
16.842 Beiträge seit 2008
vor 6 Jahren

Ja, das ist schon sehr unelegant. Im Falle des Klartext-Passwortes sogar fahrlässig.

  • Schau Dir den Repository Pattern an.
  • Speicher Passwörter niemals im Klartext, sondern gesalzen (Salt (Kryptologie))
  • Verwende Dependency Injection und vermeide Magic Strings oder Hardcoded-Stuff wie DB-Namen.
  • Erstelle Datenbanken besser mit Bibliotheken wie FluentMigrator.
  • Bei Sqlite würde ich auch Dapper als MicroORM empfehlen.
R
resper Themenstarter:in
33 Beiträge seit 2017
vor 6 Jahren

Ja, das ist schon sehr unelegant. Im Falle des Klartext-Passwortes sogar fahrlässig.

  • Schau Dir den Repository Pattern an.
  • Speicher Passwörter niemals im Klartext, sondern gesalzen (
    >
    )
  • Verwende Dependency Injection und vermeide Magic Strings oder Hardcoded-Stuff wie DB-Namen.
  • Erstelle Datenbanken besser mit Bibliotheken wie FluentMigrator.
  • Bei Sqlite würde ich auch Dapper als MicroORM empfehlen.

Passwörter: Meine MD5 Methode aus den Anwendungsbeispiel:

User login = sqlite.Login(Loginname, HelperClass.MD5Hash(Password));

versieht das Passwort mit einem Salt.

Der Rest der Punkte sind für mich ehrlich gesagt böhmische Dörfer 😉 Da werde ich mich wohl noch weiter einlesen müssen.

R
resper Themenstarter:in
33 Beiträge seit 2017
vor 6 Jahren

Also ich habe mich jetzt durch alle möglichen Beispiele gewühlt, die ich mit Hilfe von Google und den Suchbegriffen "c# wpf sqlite" gefunden habe und bin bisher kaum auf aussagekräftige Beispiele gestoßen, die sich stark von meinem zur Zeit verwendeten Code unterscheiden.

Wäre es evtl. möglich mir in Bezug auf "Verwende Dependency Injection und vermeide Magic Strings oder Hardcoded-Stuff wie DB-Namen." Beispiele in Bezug auf meinen Code aufzuzeigen?

16.842 Beiträge seit 2008
vor 6 Jahren

MD5 (vor allem ohne Salt) ist kein sicheres Verfahren. Bitte verwende Salting mit einem entsprechend sicheren Verfahren, zB SHA 512.

2.207 Beiträge seit 2011
vor 6 Jahren

Hallo resper,

Also ich habe mich jetzt durch alle möglichen Beispiele gewühlt, die ich mit Hilfe von Google und den Suchbegriffen "c# wpf sqlite" gefunden habe und bin bisher kaum auf aussagekräftige Beispiele gestoßen, die sich stark von meinem zur Zeit verwendeten Code unterscheiden.

Du musst dir immer vor Augen halten, dass Blogposts etc. die _direkte _Problemlösung auf dein Problem enthalten können. Sie sind aber selten zum copy/pasten geeignet und erklären alles andere drumherum. Somit findest du auf deinen gefundenen Artikeln zwar eine Lösung, die im besten Fall noch funktioniert, jedoch musst du sie selber in dein Programm integrieren und mit den genannten Stichworten verheiraten. Kein Artikel wird dir noch Repositories, DI etc. zusätzlich erklären, da es meistens in den gefundenen Sachen nicht darum geht.

Unter den genannten Stichworten findest du ebenfalls eine Menge Infos. Lies dich da mal ein und schau, in wie weit dir das helfen kann.
[Artikel] Drei-Schichten-Architektur

Gruss

Coffeebean

R
resper Themenstarter:in
33 Beiträge seit 2017
vor 6 Jahren

Danke für die Tipps. Ich werde weiter versuchen mich zu belesen.