{"id":55000146,"date":"2018-10-01T00:00:00","date_gmt":"2020-03-27T19:33:56","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=146"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"Entity_Framework_Datenbankinitialisierung","status":"publish","type":"post","link":"https:\/\/vbentwickler.de\/Entity_Framework_Datenbankinitialisierung\/","title":{"rendered":"Entity Framework: Datenbankinitialisierung"},"content":{"rendered":"<p><b>Wenn Sie mit Code First arbeiten, also Ihre Datenbank auf Basis eines Entity Data Models erstellt wird, k&ouml;nnen Sie verschiedene Strategien ausw&auml;hlen, um die Datenbank zu erstellen oder anzupassen, wenn Sie die Anwendung an einen anderen Benutzer weitergeben. Dieser Artikel zeigt, welche M&ouml;glichkeiten es gibt und wie diese funktionieren.<\/b><\/p>\n<p>In den letzten Ausgaben von <b>DATENBANKENTWICKLER <\/b>haben wir vermehrt mit Anwendungen gearbeitet, in denen wir ein Entity Data Model definiert haben, also verschiedene Klassen f&uuml;r die Objekte und entsprechende Auflistungen. Daraus erstellt das Entity Framework dann bei Bedarf eine Datenbank, welche die Klassen und Auflistungen ber&uuml;cksichtigt. Dabei gibt es verschiedene M&ouml;glichkeiten, die Datenbank zu erstellen, wenn diese noch nicht vorhanden ist oder diese anzupassen, wenn Sie eine neue Version der Datenbank an den Benutzer weitergeben.<\/p>\n<p>Als Voraussetzung wollen wir ein einfaches Modell heranziehen, dass nur aus den beiden Tabellen <b>Articles <\/b>und <b>Categories <\/b>besteht. Diese haben wir in einem neuen Projekt namens <b>InitializationSample <\/b>als Visual Basic-WPF-App angelegt, dem wir ein neues Objekt des Typs <b>ADO.NET Entity Data Model <\/b>f&uuml;r ein <b>Leeres Code First-Modell <\/b>namens <b>ArticleContext <\/b>hinzugef&uuml;gt haben.<\/p>\n<p>Hier legen wir im Unterordner <b>Data <\/b>die erste Klasse namens <b>Articles.vb <\/b>an:<\/p>\n<pre><span style=\"color:blue;\">Public Class<\/span> Article\r\n     <span style=\"color:blue;\">Public <\/span>Property ID<span style=\"color:blue;\"> As Integer<\/span>\r\n     <span style=\"color:blue;\">Public <\/span>Property Name<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Public <\/span>Property CategoryID<span style=\"color:blue;\"> As Integer<\/span>\r\n     <span style=\"color:blue;\">Public <\/span>Property Category<span style=\"color:blue;\"> As <\/span>Category\r\n     <span style=\"color:blue;\">Public <\/span>Property Price<span style=\"color:blue;\"> As Decimal<\/span>\r\n<span style=\"color:blue;\">End Class<\/span><\/pre>\n<p>Die zweite Klasse nimmt die Kategorien auf und hei&szlig;t <b>Categories.cs<\/b>:<\/p>\n<pre><span style=\"color:blue;\">Public Class<\/span> Category\r\n     <span style=\"color:blue;\">Public <\/span>Property ID<span style=\"color:blue;\"> As Integer<\/span>\r\n     <span style=\"color:blue;\">Public <\/span>Property Name<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Public <\/span>Property Articles<span style=\"color:blue;\"> As <\/span>ICollection(Of Article)\r\n<span style=\"color:blue;\">End Class<\/span><\/pre>\n<p>Dazu kommen zwei Zeilen, welche die Auflistungen der Elemente dieser beiden Klassen repr&auml;sentieren. Diese f&uuml;gen wir in der Klasse ein, die beim Hinzuf&uuml;gen des Entity Data Models angelegt wurde und den Namen <b>ArticleContext.vb <\/b>tr&auml;gt. Diese sieht dann so aus:<\/p>\n<pre>Imports System.Data.Entity\r\n<span style=\"color:blue;\">Public Class<\/span> ArticleContext\r\n     Inherits DbContext\r\n     <span style=\"color:blue;\">Public <\/span>Sub New()\r\n         MyBase.New(\"name=ArticleContext\")\r\n     End Sub\r\n     <span style=\"color:blue;\">Public <\/span>Property Categories()<span style=\"color:blue;\"> As <\/span>DbSet(Of Category)\r\n     <span style=\"color:blue;\">Public <\/span>Property Articles()<span style=\"color:blue;\"> As <\/span>DbSet(Of Article)\r\n<span style=\"color:blue;\">End Class<\/span><\/pre>\n<h2>Datenbank beim ersten Zugriff erstellen<\/h2>\n<p>Entity Framework hat einen Mechanismus, der daf&uuml;r sorgt, dass eine Datenbank automatisch erstellt wird, wenn Sie das erste Mal auf diese zugreifen, aber noch keine Datenbank vorhanden ist. Um dies auszuprobieren, f&uuml;gen Sie der Code behind-Klasse des Fensters <b>MainWindow.xaml <\/b>zun&auml;chst den Konstruktor hinzu und f&uuml;llen diesen dann mit den folgenden Anweisungen:<\/p>\n<pre><span style=\"color:blue;\">Class<\/span> MainWindow\r\n     <span style=\"color:blue;\">Public <\/span>Sub New()\r\n         Using dbContext<span style=\"color:blue;\"> As <\/span>ArticleContext = <span style=\"color:blue;\">New<\/span> ArticleContext\r\n             <span style=\"color:blue;\">Dim <\/span>MyCategory<span style=\"color:blue;\"> As <\/span>Category\r\n             MyCategory = <span style=\"color:blue;\">New<\/span> Category()\r\n             MyCategory.Name = \"Getr&auml;nke\"\r\n             dbContext.Categories.Add(MyCategory)\r\n             dbContext.SaveChanges()\r\n         End Using\r\n     End Sub\r\n<span style=\"color:blue;\">End Class<\/span><\/pre>\n<p>Die Methode <b>New <\/b>erstellt einen neuen Kontext auf Basis der Klasse <b>ArticleContext <\/b>und speichert diese in der Variablen <b>dbContext<\/b>. Dann erstellen wir ein neues Objekt des Typs <b>Category<\/b>, weisen der Eigenschaft <b>Name <\/b>den Wert <b>Getr&auml;nke <\/b>zu und f&uuml;gen das neue Objekt zur Auflistung <b>Categories <\/b>des Objekts <b>dbContext <\/b>hinzu. Die &Auml;nderungen speichern wir dann mit der Methode <b>SaveChanges<\/b>.<\/p>\n<p>Nun brauchen Sie die Anwendung nur noch zu starten. Es dauert dann ein wenig l&auml;nger bis zum Erscheinen des Anwendungsfensters, aber daf&uuml;r wird in der Zwischenzeit auch gleich die Datenbank erstellt.<\/p>\n<p>Diese finden Sie dann nach dem Beenden der Anwendung unter Visual Studio im SQL Server-Objekt-Explorer, den Sie mit dem Men&uuml;befehl <b>Ansicht|SQL Server-Objekt-Explorer <\/b>einblenden k&ouml;nnen. Hier klappen Sie den Eintrag <b>Datenbanken <\/b>auf und finden die Datenbank <b>InitializationSample.ArticleContext <\/b>vor (siehe Bild 1).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2018_05\/pic_146_001.png\" alt=\"Die neue Datenbank im SQL Server-Objekt-Explorer\" width=\"424,7115\" height=\"326,7012\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 1: Die neue Datenbank im SQL Server-Objekt-Explorer<\/span><\/b><\/p>\n<p>Wenn Sie nun noch das Kontextmen&uuml; des Eintrags <b>dbo.Categories <\/b>&ouml;ffnen und dort den Befehl <b>Daten anzeigen <\/b>ausw&auml;hlen, erscheinen die Daten der Tabelle <b>Categories <\/b>&#8211; in diesem Fall der eine in der Konstruktor-Methode angelegte Datensatz mit dem Wert <b>Getr&auml;nke <\/b>im Feld <b>Name<\/b>.<\/p>\n<h2>Ergebnisse beim Anlegen der Datenbank<\/h2>\n<p>Schauen wir uns an, was im Detail geschehen ist. Als Erstes ist festzuhalten: Es wurde eine Datenbank angelegt, und zwar auf dem Server <b>(LocalDb)\\MSSQLLocalDB <\/b>und unter dem Namen <b>InitializationSample.ArticleContext<\/b>.<\/p>\n<p>Wenn Sie diese Einstellung &auml;ndern wollen, k&ouml;nnen Sie das in der Datei <b>App.config <\/b>(f&uuml;r Desktop-Anwendungen) oder <b>Web.config <\/b>(f&uuml;r Web-Anwendungen) erledigen, wo Sie den folgenden Abschnitt anpassen m&uuml;ssen:<\/p>\n<pre>&lt;connectionStrings&gt;\r\n     &lt;add name=\"ArticleContext\" connectionString=\"data source=(LocalDb)\\MSSQLLocalDB;        initial catalog=InitializationSample.ArticleContext;integrated security=True;MultipleActiveResultSets=True;        App=EntityFramework\" providerName=\"System.Data.SqlClient\" \/&gt;\r\n&lt;\/connectionStrings&gt;<\/pre>\n<p>Woher wei&szlig; Entity Framework, dass es genau diese Verbindungszeichenfolge nutzen soll Wir sehen hier, dass diese den Namen ArticleContext aufweist. Dieser wird in der Konstruktor-Methode der Klasse ArticleContext.vb, die mit dem Entity Data Model erstellt wurde, referenziert:<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>New()\r\n     MyBase.New(\"name=ArticleContext\")\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Wenn Sie also eine andere Verbindungszeichenfolge nutzen wollen, stellen Sie diese hier ein.<\/p>\n<h2>Alternativer Datenbankname<\/h2>\n<p>W&auml;hrend wir dem New-Konstruktor von MyBase soeben den Namen der Verbindungszeichenfolge &uuml;bergeben haben, k&ouml;nnen Sie hier auch den Namen der zu erstellenden Datenbank angeben. Dazu lassen Sie einfach den Namen des Parameters weg und geben direkt den gew&uuml;nschten Datenbanknamen an, zum Beispiel InitializationSample:<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>New()\r\n     MyBase.New(\"InitializationSample\")\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Sie k&ouml;nnen aber auch einfach den Namen der Datenbank in der Verbindungszeichenfolge anpassen. Diesen finden Sie unter dem Parameternamen initial catalog.<\/p>\n<h2>Tabellen erstellen<\/h2>\n<p>Welche Tabellen Entity Framework in der neuen Datenbank erstellen soll, entnimmt es ebenfalls der Klasse ArticleContext.vb. Hier ber&uuml;cksichtigt es einfach alle als DbSet deklarierten &ouml;ffentlichen Eigenschaften, also aktuell diese hier:<\/p>\n<pre><span style=\"color:blue;\">Public Property <\/span>Categories()<span style=\"color:blue;\"> As <\/span>DbSet(Of Category)\r\n<span style=\"color:blue;\">Public Property <\/span>Articles()<span style=\"color:blue;\"> As <\/span>DbSet(Of Article)<\/pre>\n<h2>Felder hinzuf&uuml;gen<\/h2>\n<p>Nun fehlen noch die Felder. Welche Entity Framework hier hinzuf&uuml;gen muss, entnimmt es der Definition der Klassen, die in den DbSet-Objekten angegeben sind (zum Beispiel DbSet(Of Category)).<\/p>\n<p>Wie Sie die Felder anlegen m&uuml;ssen, damit beispielsweise Beziehungen zwischen den Tabellen in der Zieldatenbank entstehen, erfahren Sie in den Artikeln EDM: 1:n-Beziehungen per Code First, EDM: 1:1-Beziehungen per Code First und EDM: m:n-Beziehungen per Code First.<\/p>\n<h2>Der n&auml;chste Start<\/h2>\n<p>Wenn Sie die Anwendung nun nochmals &ouml;ffnen, ist die Datenbank bereits vorhanden. Entity Framework muss diese dann nicht erneut anlegen und kann die vorhandene Datenbank verwenden.<\/p>\n<h2>&Auml;nderungen am Datenmodell<\/h2>\n<p>Wenn Sie nun eine &Auml;nderung am Datenmodell vornehmen, indem Sie etwa das Feld Description zur Klasse Article hinzuf&uuml;gen, wollen Sie diese &Auml;nderung nat&uuml;rlich auch auf das Datenmodell einer eventuell bereits existierenden Datenbank &uuml;bertragen. Also probieren wir aus, was nach der folgenden Anpassung und einem Neustart der Anwendung geschieht:<\/p>\n<pre><span style=\"color:blue;\">Public Class<\/span> Article\r\n     ...\r\n     <span style=\"color:blue;\">Public <\/span>Property Description<span style=\"color:blue;\"> As String<\/span>\r\n<span style=\"color:blue;\">End Class<\/span><\/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\/55000146\/\">\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\/55000146?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\/55000146\/\"\/>\n\t\t\t\t<input type=\"hidden\" name=\"rcp_login_nonce\" value=\"22c77db969\"\/>\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>Wenn Sie mit Code First arbeiten, also Ihre Datenbank auf Basis eines Entity Data Models erstellt wird, k&ouml;nnen Sie verschiedene Strategien ausw&auml;hlen, um die Datenbank zu erstellen oder anzupassen, wenn Sie die Anwendung an einen anderen Benutzer weitergeben. Dieser Artikel zeigt, welche M&ouml;glichkeiten es gibt und wie diese funktionieren.<\/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":[662018,66052018,44000021],"tags":[],"yst_prominent_words":[],"class_list":["post-55000146","post","type-post","status-publish","format-standard","hentry","category-662018","category-66052018","category-Entity_Framework"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000146","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=55000146"}],"version-history":[{"count":0,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000146\/revisions"}],"wp:attachment":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/media?parent=55000146"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/categories?post=55000146"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/tags?post=55000146"},{"taxonomy":"yst_prominent_words","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/yst_prominent_words?post=55000146"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}