{"id":55000089,"date":"2017-06-01T00:00:00","date_gmt":"2020-03-27T19:26:52","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=89"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"Entity_Framework_SQLite_verknuepfen","status":"publish","type":"post","link":"https:\/\/vbentwickler.de\/Entity_Framework_SQLite_verknuepfen\/","title":{"rendered":"Entity Framework: SQLite verkn&uuml;pfen"},"content":{"rendered":"<p><b>In den letzten Artikel haben wir oft die SQLite-Datenbank als Beispieldatenbank verwendet. Nun kann es allerdings durch einen falschen Connection-String oder eine verschobene, gel&ouml;schte oder leere Datenbank dazu kommen, dass die Anwendung nicht &uuml;ber das Entity Framework auf die Datenbank zugreifen kann. Dieser Artikel beschreibt einige Szenarien, in denen das der Fall ist und zeigt, wie Sie beim Start der Anwendung pr&uuml;fen k&ouml;nnen, ob die Quell-Datenbank erreichbar ist und diese gegebenenfalls neu ausw&auml;hlen.<\/b><\/p>\n<p>Die SQLite-Datenbank ist eine sehr praktische Datenquelle f&uuml;r einfache Anwendungen, die keinen SQL Server ben&ouml;tigen. Sie kommt als eine einzige Datei daher und die Treiber k&ouml;nnen bequem in ein Projekt integriert werden &#8211; auch die Weitergabe ist &uuml;berhaupt kein Problem. Was aber ein Problem sein k&ouml;nnte, wissen Access-Entwickler, die Datenbanken in Front- und Backend aufgeteilt haben, nur zu gut: Die Datenbankdatei k&ouml;nnte sich nicht an dem Ort befinden, der in der Verbindungszeichenfolge des Frontends angegeben ist.<\/p>\n<p>Mit einem .NET-WPF-Projekt und einer SQLite-Datenbank haben Sie ein klassisches Frontend-Backend-Szenario, wie es auch bei aufgeteilten Access-Datenbanken vorliegt. Im Gegensatz zur Konstellation mit einem SQL Server haben Sie keine Server-Angabe im Connection-String, sondern Sie m&uuml;ssen den Namen der Datenbank, gegebenenfalls mit Angabe des Pfades zu dieser Datenbank, angeben. Wenn Sie ein Entity Data Model zu Ihrem Projekt hinzugef&uuml;gt und die Datenbankdatei, zum Beispiel <b>Bestellverwaltung.db<\/b>, als Datenquelle ausgew&auml;hlt haben, schreibt der Entity Data Model-Assistent eine Verbindungszeichenfolge in die Datei <b>App.config<\/b>, die etwa wie folgt aussieht:<\/p>\n<pre>&lt;configuration&gt;\r\n   ...\r\n   &lt;connectionStrings&gt;\r\n     &lt;add name=\"BestellverwaltungEntities\" connectionString=\"...;provider=System.Data.SQLite.EF6;provider connection \r\n         string=&quot;data source=c:\\Beispiel\\Bestellverwaltung.db&quot;\" providerName=\"System.Data.EntityClient\" \/&gt;\r\n   &lt;\/connectionStrings&gt;\r\n&lt;\/configuration&gt;<\/pre>\n<p>Hier sehen Sie, dass der Assistent zum Erstellen des Entity Data Models den absoluten Pfad zur Datenbankdatei <b>Bestellverwaltung.db <\/b>angegeben hat. Das geht solange gut, wie Sie die Anwendung auf dem Entwicklungsrechner debuggen oder einsetzen und die Datenbank sich an Ort und Stelle befindet.<\/p>\n<p>Wenn Sie jedoch die Anwendung auf einen anderen Rechner verschieben, ist die Wahrscheinlichkeit hoch, dass die Datenbankdatei unter diesem Pfad nicht mehr zu erreichen ist. Ich selbst programmiere beispielsweise auf zwei verschiedenen Rechnern, wobei die Dateien per DropBox jeweils auf den aktuellsten Stand gebracht werden. Und sobald das Projekt samt Datenbankdatei auf dem einen Rechner nicht auf dem gleichen Pfad wie auf dem anderen Rechner liegt, findet eines der beiden Projekte die Datenbankdatei nicht mehr.<\/p>\n<h2>Relativ statt absolut<\/h2>\n<p>In diesem Fall ist die erste Ma&szlig;nahme, den Pfad aus der Angabe der Quelldatenbank zu entfernen und nur noch den Dateinamen anzugeben. Das sieht dann in der Datei <b>App.config <\/b>wie folgt aus:<\/p>\n<pre>&lt;configuration&gt;\r\n   ...\r\n   &lt;connectionStrings&gt;\r\n     &lt;add name=\"BestellverwaltungEntities\" connectionString=\"...;provider=System.Data.SQLite.EF6;provider connection \r\n         string=&quot;data source=Bestellverwaltung.db&quot;\" providerName=\"System.Data.EntityClient\" \/&gt;\r\n   &lt;\/connectionStrings&gt;\r\n&lt;\/configuration&gt;<\/pre>\n<p>Dies bedeutet nun nichts anderes, als dass die Datenbankdatei nun immer dann erreichbar ist, wenn sich diese im gleichen Verzeichnis wie die <b>.exe<\/b>-Datei des Projekts befindet.<\/p>\n<h2>Mehrbenutzer-Szenario<\/h2>\n<p>Das wird in einem Mehrbenutzer-Szenario nat&uuml;rlich nicht mehr funktionieren, denn schon wenn die Anwendung auf zwei Rechnern installiert ist, m&uuml;sste man auf einem Rechner den absoluten Pfad zu der zu nutzenden Datenbankdatei hinterlegen.<\/p>\n<p>Wir ben&ouml;tigen also einen Mechanismus, der beim Start der Anwendung ausgel&ouml;st wird und pr&uuml;ft, ob die zu verwendende Datenbankdatei verf&uuml;gbar ist. Wenn dies nicht der Fall ist, soll ein Dialog erscheinen, mit dem der Benutzer die Datenbankdatei ausw&auml;hlen soll. Diese &Auml;nderung sollte dann optimalerweise irgendwo in den Einstellungen der Datenbank gespeichert und von nun an beim Start abgerufen werden k&ouml;nnen. Wir beginnen jedoch mit der Pr&uuml;fung, ob die Datenbankdatei &uuml;berhaupt an Ort und Stelle ist. Dies erledigen wir beim Start der Anwendung, und zwar beim Aufruf des Hauptfensters.<\/p>\n<h2>Beispielkonstellation<\/h2>\n<p>Wir erstellen im Fenster MainWindow eine minimale Konfiguration, um die Kunden aus der Datenbank <b>Bestellverwaltung.db <\/b>in einem DataGrid anzuzeigen. Dazu f&uuml;gen Sie <b>MainWindow.xaml <\/b>folgenden Code hinzu:<\/p>\n<pre>&lt;Grid&gt;\r\n     &lt;DataGrid ItemsSource=\"{Binding Kunden}\"&gt;&lt;\/DataGrid&gt;\r\n&lt;\/Grid&gt;<\/pre>\n<p>Das Code behind-Modul MainWindow.xaml.cs statten wir so aus:<\/p>\n<pre>using System.Windows;\r\nusing System.Collections.ObjectModel;\r\nnamespace TestDatenbankVorhanden {\r\n     public partial class MainWindow : Window {\r\n         BestellverwaltungEntities dbContext = null;\r\n         private ObservableCollection&lt;Kunde&gt; kunden;\r\n         public ObservableCollection&lt;Kunde&gt; Kunden {\r\n             get { return kunden; }\r\n             set { kunden = value; }\r\n         }\r\n         public MainWindow() {\r\n             InitializeComponent();\r\n             dbContext = new BestellverwaltungEntities();\r\n             kunden = new ObservableCollection&lt;Kunde&gt;(dbContext.Kunden);\r\n             DataContext = this;\r\n         }\r\n     }\r\n}<\/pre>\n<p>Damit werden die Daten im Fenster angezeigt.<\/p>\n<h2>Datenquelle entfernen<\/h2>\n<p>Was geschieht nun, wenn wir die Datenquelle vom gewohnten Ort entfernen Dazu wechseln Sie im Windows Explorer zum Verzeichnis <b>bin|Debug <\/b>unterhalb des Projektordners und benennen die Datei <b>Bestellverwaltung.db <\/b>um, zum Beispiel in <b>_Bestellverwaltung.db<\/b>. Starten Sie die Anwendung nun von diesem Verzeichnis aus per Doppelklick auf den Namen der <b>.exe<\/b>-Datei (im Falle der Beispielanwendung <b>TestDatenbankVorhanden.exe<\/b>). Werden die Daten nun immer noch angezeigt Dann stehen die Chancen gut, dass Sie im Connection-String noch den absoluten Pfad zur Datei <b>Bestellverwaltung.db <\/b>stehen haben und die <b>.exe<\/b>-Datei auf diese Datei zugreift. Entfernen Sie hier zun&auml;chst, wie oben beschrieben, die Pfadangabe, sodass nur noch der Dateiname <b>Bestellverwaltung.db <\/b>im Connection-String steht. Starten Sie das Projekt dann neu, damit die Anwendung mit der neuen Verbindungszeichenfolge im Verzeichnis <b>bin\/Debug <\/b>landet. Dadurch wird nun auch wieder die Datei <b>Bestellverwaltung.db <\/b>eingetragen, deren Namen Sie ja soeben schon in <b>_Bestellverwaltung.db <\/b>ge&auml;ndert haben. Beenden Sie die Anwendung also wieder und benennen Sie die Datei <b>Bestellverwaltung.db <\/b>erneut in <b>_Bestellverwaltung.db <\/b>um. Starten Sie dann die Anwendung <b>TestDatenbankVorhanden.exe <\/b>erneut. Was geschieht nun Normalerweise sollte nun nichts Sichtbares geschehen &#8211; die Anwendung wird einfach nicht gestartet. Das liegt daran, dass wir keine Fehlerbehandlung eingebaut haben, die Anwendung aber beim Aufrufen einen Fehler ausl&ouml;st, denn die Datenquelle ist ja nicht verf&uuml;gbar. Interessanterweise finden Sie im Verzeichnis <b>bin\/Debug <\/b>aber nun eine neuen Datei namens <b>Bestellverwaltung.db <\/b>mit einer Gr&ouml;&szlig;e von <b>0 KB <\/b>vor. Dies geschieht, weil das Entity Framework eine neue Datenbankdatei erstellt, wenn beim Versuch des Zugriffs keine entsprechende Datenbankdatei gefunden werden konnte.<\/p>\n<h2>Fehler per Exception-Handling aufdecken<\/h2>\n<p>Wir wollen die Anwendung also nun mit einer Fehlerbehandlung erweitern, damit wir die Fehlermeldung erhalten und entsprechend darauf reagieren k&ouml;nnen. Unsere Vermutung ist, dass der Fehler beim Zugriff auf die <b>Kunden<\/b>-Liste auftritt. Die betroffene Anweisung fassen wir also in einen <b>try<\/b>-Block ein. Zusammen mit dem <b>catch<\/b>-Block sieht das Ganze nun wie folgt aus:<\/p>\n<pre>try {\r\n     kunden = new ObservableCollection&lt;Kunde&gt;(dbContext.Kunden);\r\n}\r\ncatch (Exception e) {\r\n     MessageBox.Show(\"Error:\\n\\n\" + e.Message + \"\\n\\n\" + e.InnerException.Message);\r\n}<\/pre>\n<div class=\"rcp_restricted\"><p><span style=\"color: #ff0000;\">M&ouml;chten Sie weiterlesen? Dann l&ouml;sen Sie Ihr Ticket!<\/span><br \/>\n<span style=\"color: #ff0000;\">Hier geht es zur Bestellung des Jahresabonnements des Magazins <strong>Visual Basic Entwickler<\/strong>:<\/span><br \/>\n<span style=\"color: #ff0000;\"><a style=\"color: #ff0000;\" href=\"https:\/\/shop.minhorst.com\/magazine\/363\/visual-basic-entwickler-jahresabonnement?c=77\">Zur Bestellung ...<\/a><\/span><br \/>\n<span style=\"color: #ff0000;\">Danach greifen Sie sofort auf <strong>alle rund 200 Artikel<\/strong> unseres Angebots zu - auch auf diesen hier!<\/span><br \/>\n<span style=\"color: #000000;\">Oder haben Sie bereits Zugangsdaten? Dann loggen Sie sich gleich hier ein:<\/span><\/p>\n<\/div>\n\n\t\n\t<form id=\"rcp_login_form\"  class=\"rcp_form\" method=\"POST\" action=\"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000089\/\">\n\n\t\t\n\t\t<fieldset class=\"rcp_login_data\">\n\t\t\t<p>\n\t\t\t\t<label for=\"rcp_user_login\">Username or Email<\/label>\n\t\t\t\t<input name=\"rcp_user_login\" id=\"rcp_user_login\" class=\"required\" type=\"text\"\/>\n\t\t\t<\/p>\n\t\t\t<p>\n\t\t\t\t<label for=\"rcp_user_pass\">Password<\/label>\n\t\t\t\t<input name=\"rcp_user_pass\" id=\"rcp_user_pass\" class=\"required\" type=\"password\"\/>\n\t\t\t<\/p>\n\t\t\t\t\t\t<p>\n\t\t\t\t<input type=\"checkbox\" name=\"rcp_user_remember\" id=\"rcp_user_remember\" value=\"1\"\/>\n\t\t\t\t<label for=\"rcp_user_remember\">Remember me<\/label>\n\t\t\t<\/p>\n\t\t\t<p class=\"rcp_lost_password\"><a href=\"\/data\/wp\/v2\/posts\/55000089?rcp_action=lostpassword\"><\/a><\/p>\n\t\t\t<p>\n\t\t\t\t<input type=\"hidden\" name=\"rcp_action\" value=\"login\"\/>\n\t\t\t\t<input type=\"hidden\" name=\"rcp_redirect\" value=\"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000089\/\"\/>\n\t\t\t\t<input type=\"hidden\" name=\"rcp_login_nonce\" value=\"a72fca7b92\"\/>\n\t\t\t\t<input id=\"rcp_login_submit\" class=\"rcp-button\" type=\"submit\" value=\"Login\"\/>\n\t\t\t<\/p>\n\t\t\t\t\t<\/fieldset>\n\n\t\t\n\t<\/form>\n<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In den letzten Artikel haben wir oft die SQLite-Datenbank als Beispieldatenbank verwendet. Nun kann es allerdings durch einen falschen Connection-String oder eine verschobene, gel&ouml;schte oder leere Datenbank dazu kommen, dass die Anwendung nicht &uuml;ber das Entity Framework auf die Datenbank zugreifen kann. Dieser Artikel beschreibt einige Szenarien, in denen das der Fall ist und zeigt, wie Sie beim Start der Anwendung pr&uuml;fen k&ouml;nnen, ob die Quell-Datenbank erreichbar ist und diese gegebenenfalls neu ausw&auml;hlen.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[662017,66032017,44000021,44000027,44000006],"tags":[],"yst_prominent_words":[],"class_list":["post-55000089","post","type-post","status-publish","format-standard","hentry","category-662017","category-66032017","category-Entity_Framework","category-Excel_programmieren","category-SQL_Server_und_Co"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000089","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/comments?post=55000089"}],"version-history":[{"count":0,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000089\/revisions"}],"wp:attachment":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/media?parent=55000089"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/categories?post=55000089"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/tags?post=55000089"},{"taxonomy":"yst_prominent_words","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/yst_prominent_words?post=55000089"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}