{"id":55000048,"date":"2016-08-01T00:00:00","date_gmt":"2020-03-27T19:21:24","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=48"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"LINQ_to_Entities_Daten_abfragen","status":"publish","type":"post","link":"https:\/\/vbentwickler.de\/LINQ_to_Entities_Daten_abfragen\/","title":{"rendered":"LINQ to Entities: Daten abfragen"},"content":{"rendered":"<p><b>In den vorangegangenen Ausgaben von DATENBANKENTWICKLER haben Sie bereits erfahren, wie Sie per ADO.NET auf die Daten der Tabellen einer Datenbank zugreifen. Nun nutzen wir nicht mehr direkt ADO.NET, sondern das Entity Framework als Datenlieferant, welches eine ganz andere Art des Zugriffs erm&ouml;glicht. Dieser Artikel zeigt, wie Sie per C#-Konsolenanwendung auf die per Entity Data Model bereitgestellten Daten zugreifen.<\/b><\/p>\n<h2>Beispielprojekt<\/h2>\n<p>Das Beispielprojekt soll &uuml;ber ein geeignetes Entity Data Model auf die Tabellen einer LocalDB-Datenbank zugreifen. Wie Sie das Entity Data Model erstellen, beschreiben wir im Artikel Entity Data Model f&uuml;r eine Datenbank erstellen.<\/p>\n<p>Alle Beispielmethoden finden Sie in der Klasse EDM_ZugriffPerCSharp_Beispiele.cs. Um die Beispiele auszuprobieren, starten Sie einfach das Projekt.<\/p>\n<h2>Aufruf der Beispielmethoden<\/h2>\n<p>Damit wir die nachfolgend programmierten Methoden einfach aufrufen k&ouml;nnen, verwenden wir wieder die bereits in fr&uuml;heren Artikeln verwendete Klasse Program mit einer Main-Methode, die alle &ouml;ffentlichen, statischen Methoden aus &ouml;ffentlichen Klassen auflistet und zur Ausf&uuml;hrung anbietet. In einer neuen Klasse namens EDM_ZugriffPerCSharp_Beispiele.cs legen wir dann die sp&auml;ter vorgestellten Methoden an.<\/p>\n<h2>LINQ to Entities<\/h2>\n<p>Die Abfragesprache f&uuml;r den Zugriff auf die Daten des Entity Frameworks und damit auf das Entity Data Model hei&szlig;t LINQ to Entities.<\/p>\n<h2>Zugriff auf die Daten der Tabelle Anrede<\/h2>\n<p>Unter Access w&uuml;rden Sie nun, wenn Sie alle Datens&auml;tze einer Tabelle wie etwa Anrede durchlaufen wollten, ein Database-Objekt und ein Recordset-Objekt erzeugen, Letzteres mit einer entsprechenden SQL-Anweisung f&uuml;llen und dann per VBA in einer Do While-Schleife durch die einzelnen Datens&auml;tze navigieren. Unter C# und dem Entity Framework sieht das etwas anders aus &#8211; im &Uuml;berblick wie in Listing 1. Hier nutzen Sie ein automatisch generiertes Objekt, das die Klasse DbContext implementiert, die in unserem Fall beispielsweise Bestellverwaltung-Entities hei&szlig;t.<\/p>\n<pre>public static void AlleAnredenAusgeben_ForEach() {\r\n     BestellverwaltungEntities context = new BestellverwaltungEntities();\r\n     var anreden = context.Anreden;\r\n     foreach (var anrede in anreden) {\r\n         Console.WriteLine(\"{0} {1}\", anrede.ID, anrede.Bezeichnung);\r\n     }\r\n}<\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 1: Methode zur Ausgabe aller Anreden der Beispieldatenbank<\/span><\/b><\/p>\n<p>Wir erstellen ein neues Objekt auf Basis dieses Typs und speichern es in der Variablen context:<\/p>\n<pre>BestellverwaltungEntities context = \r\n                           new BestellverwaltungEntities();<\/pre>\n<p>Dann definieren wir eine Variable des Typs var und nennen diese anreden. Sie soll mit der Liste der Anreden des Objekts context gef&uuml;llt werden:<\/p>\n<pre>var anreden = context.Anreden;<\/pre>\n<p>Schlie&szlig;lich durchlaufen wir die Elemente der Auflistung <b>anreden <\/b>in einer <b>foreach<\/b>-Schleife und weisen das jeweils aktuelle Objekt der Variablen <b>anrede <\/b>zu. Innerhalb der Schleife geben wir dann die Werte der Eigenschaften <b>ID <\/b>und <b>Bezeichnung <\/b>aller Elemente aus:<\/p>\n<pre>foreach (var anrede in anreden) {\r\n     Console.WriteLine(\"{0} {1}\", \r\n                            anrede.ID, anrede.Bezeichnung);\r\n}<\/pre>\n<p>Das Ergebnis sieht etwa so aus:<\/p>\n<pre>1 Herr\r\n2 Frau<\/pre>\n<p>Praktischerweise blendet Visual Studio beim Eingeben der Eigenschaften f&uuml;r das Objekt <b>anrede<\/b> per IntelliSense die verf&uuml;gbaren Eintr&auml;ge ein (siehe Bild 1).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2016_04\/pic_48_001.png\" alt=\"IntelliSense f&uuml;r den Datenzugriff\" width=\"599,593\" height=\"382,5623\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 1: IntelliSense f&uuml;r den Datenzugriff<\/span><\/b><\/p>\n<p>Fertig &#8211; damit w&auml;re der erste Zugriff auf die Daten der Tabelle <b>Anreden<\/b> unserer Beispieldatenbank schon erledigt! Im Folgenden sehen wir uns nun weitere M&ouml;glichkeiten an.<\/p>\n<h2>Verbesserung: using verwenden<\/h2>\n<p>Damit die Verbindung zur Datenbank nach dem Abrufen der Daten wieder geschlossen wird, fassen Sie die f&uuml;r den Datenzugriff verwendeten Methoden in ein <b>using<\/b>-Konstrukt ein. Der Grund, ohne weitere Erl&auml;uterungen: Die <b>DbContext<\/b>-Klasse, von der unsere Klasse erbt, implementiert das Interface <b>IDisposable<\/b>. Die Nutzung solcher Objekte sollte man innerhalb der <b>using<\/b>-Direktive realisieren. Auf diese Weise wird beim Verlassen des von der <b>using<\/b>-Direktiven eingefassten Abschnitts auf jeden Fall die <b>Dispose<\/b>-Methode aufgerufen, was zum Beispiel die genutzten Ressourcen wieder freigibt. Die verbesserte Version des vorherigen Beispiels sieht nun wie in Listing 2 aus.<\/p>\n<pre>public static void AlleAnredenAusgeben_ForEach_Besser() {\r\n     using (BestellverwaltungEntities context = new BestellverwaltungEntities()) {\r\n         var anreden = context.Anreden;\r\n         foreach (var anrede in anreden) {\r\n             Console.WriteLine(\"{0} {1}\", anrede.ID, anrede.Bezeichnung);\r\n         }\r\n     }\r\n     Console.ReadLine();\r\n}<\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 2: Methode zur Ausgabe aller Anreden der Beispieldatenbank mit using<\/span><\/b><\/p>\n<p>Achtung: Die <b>using<\/b>-Variante funktioniert nicht wie gew&uuml;nscht, wenn Sie die der <b>using<\/b>-Direktiven &uuml;bergebene Variable bereits vorher deklarieren, wie es hier der Fall ist. Die Variable existiert dann auch noch nach Verlassen von <b>using<\/b>:<\/p>\n<pre>BestellverwaltungEntities context = \r\n                            new BestellverwaltungEntities()\r\nusing (context) {\r\n     ...  }<\/pre>\n<h2>Kunden sortiert ausgeben<\/h2>\n<p>Wenn Sie die Daten einer Tabelle sortiert erhalten m&ouml;chten, k&ouml;nnen Sie das durch eine Erweiterung einer Abfrage erreichen. Alle Kunden in unsortierter Reihenfolge w&uuml;rde folgendes Statement liefern:<\/p>\n<pre>var kunden = context.Kunden;<\/pre>\n<p>Wenn Sie eine Sortierung hinzuf&uuml;gen wollen, etwa nach dem Feld <b>Nachname<\/b>, haben Sie zwei M&ouml;glichkeiten &#8211; eine mit der Methodensyntax und eine mit der Abfragesyntax.<\/p>\n<h2>Abfragen mit der Methodensyntax<\/h2>\n<p>F&uuml;r beide f&uuml;gen Sie zun&auml;chst eine Referenz auf den Namespace <b>System.Linq <\/b>zur Klassendatei hinzu:<\/p>\n<pre>using System.Linq;<\/pre>\n<p>Nun erstellen Sie eine Methode wie in Listing 3. Der Unterschied zur Ermittlung der unsortierten Kunden liegt in der folgenden Zeile:<\/p>\n<pre>public static void KundenNachNachname_MethodenSyntax() {\r\n     using (BestellverwaltungEntities context = new BestellverwaltungEntities()) {\r\n         var kunden = context.Kunden.OrderBy(d =&gt; d.Nachname);\r\n         foreach (var kunde in kunden) {\r\n             Console.WriteLine(\"{0} {1}\", kunde.ID, kunde.Nachname);\r\n         }\r\n     }\r\n     Console.ReadLine();\r\n}<\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 3: Methode zur Ausgabe der Kunden, sortiert nach dem Nachnamen (Methodensyntax)<\/span><\/b><\/p>\n<pre>var kunden = context.Kunden.OrderBy(d =&gt; d.Nachname);<\/pre>\n<p>Hier haben wir noch die Methode <b>OrderBy <\/b>an die Eigenschaft <b>Kunden <\/b>angeh&auml;ngt und dieser als Parameter die Vorgabe f&uuml;r die Sortierung mitgegeben, n&auml;mlich <b>d => d.Nachname<\/b>.<\/p>\n<p>Dabei handelt es sich um einen sogenannten Lambda-Ausdruck. Lambda-Ausdr&uuml;cke haben wir in diesem Magazin noch nicht besprochen, daher gehen wir hier nur darauf ein, wie diese f&uuml;r den vorliegenden Anwendungszweck formuliert werden.<\/p>\n<p>Der Lambda-Ausdruck, den wir hier als Parameter der <b>OrderBy <\/b>(und sp&auml;ter auch der <b>OrderByDescending<\/b>-, der <b>Where<\/b>&#8211; und anderer Methoden) nutzen, enth&auml;lt zwei Teile: Der Teil vor dem Lambda-Zeichen (<b>=><\/b>, nicht zu verwechseln mit <b>=><\/b>) enth&auml;lt den Namen f&uuml;r das, was wir im Teil hinter dem Lambda-Zeichen untersuchen wollen.<\/p>\n<p>Wir untersuchen immer das Objekt, f&uuml;r das wir die Methode <b>OrderBy <\/b>(<b>OrderByDescending<\/b>, <b>Where<\/b>, &#8230;) aufrufen, in diesem Fall also <b>context.Kunde<\/b>, also die Auflistung der Kunden-Entit&auml;ten, und geben dieser im vorliegenden Fall den Namen <b>d<\/b> (Sie k&ouml;nnen auch einen anderen Buchstaben oder Ausdruck statt <b>d <\/b>verwenden).<\/p>\n<p>Dies k&ouml;nnen wir dann im zweiten Teil des Lambda-Ausdrucks aufgreifen. Im Falle der <b>OrderBy<\/b>-Methode geben wir also beispielsweise an, wonach wir sortieren wollen &#8211; hier die Eigenschaft <b>Nachname <\/b>der <b>Kunde<\/b>-Entit&auml;ten.<\/p>\n<p>In der Variablen <b>kunden <\/b>landet dann die sortierte Liste der <b>Kunde<\/b>-Entit&auml;ten, die wir wieder in einer <b>foreach<\/b>-Schleife durchlaufen. Diesmal geben wir den Prim&auml;rschl&uuml;sselwert sowie den Nachnamen der Kunden aus:<\/p>\n<pre>8 Ackermann\r\n9 Alberts\r\n10 Becker\r\n11 Fr&ouml;hlich\r\n4 Meier\r\n1 Minhorst\r\n2 M&uuml;ller\r\n7 Schmidt<\/pre>\n<h2>Abfragen mit der Abfragesyntax<\/h2>\n<p>Die zweite Methode zum Abfragen von Daten unter LINQ to Entities verwendet die sogenannte Abfragesyntax. Hier stellen Sie einen Abfrageausdruck zusammen, der eher wie ein SQL-Ausdruck aussieht. Um das gleiche Ergebnis wie im obigen Beispiel mit der Methodensyntax zu erzielen, ersetzen Sie die Zeile mit der <b>OrderBy<\/b>-Methode und dem Lambda-Ausdruck durch die folgende Zeile:<\/p>\n<pre>var kunden = \r\nfrom d in context.Kunden \r\norderby d.Nachname \r\nselect d;<\/pre>\n<p>Dies sieht f&uuml;r erfahrene SQL-Nutzer etwas intuitiver aus, da hier einige Elemente wie <b>from<\/b>, <b>orderby <\/b>und <b>select <\/b>auftauchen. Die Reihenfolge ist hier etwas anders als beim Lambda-Ausdruck. Die Zuweisung des Ergebnisses erfolgt wieder an die Variable <b>kunden<\/b>. Danach geben wir an, woher die Daten kommen und welchen Alias-Namen wir nachfolgend daf&uuml;r verwenden wollen (<b>from d in context.Kunden<\/b>).<\/p>\n<p>Dann legen wir die Operation fest, in diesem Fall wieder die Sortierung (<b>orderby d.Nachname<\/b>). Schlie&szlig;lich gibt <b>select d <\/b>an, was zur&uuml;ckgegeben werden soll. Beim vollst&auml;ndigen Beispiel &auml;ndert sich also nur die Zeile mit der Definition der Abfrage (siehe Listing 4).<\/p>\n<pre>public static void KundenNachNachname_Abfragesyntax() {\r\n     using (BestellverwaltungEntities context = new BestellverwaltungEntities()) {\r\n         var kunden = from d in context.Kunden orderby d.Nachname select d;\r\n         foreach (var kunde in kunden) {\r\n             Console.WriteLine(\"{0} {1}\", kunde.ID, kunde.Nachname);\r\n         }\r\n     }\r\n     Console.ReadLine();\r\n}<\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 4: Methode zur Ausgabe der Kunden, sortiert nach dem Nachnamen (Abfragesyntax)<\/span><\/b><\/p>\n<p>Sowohl bei der Methodensyntax als auch bei der Abfragensyntax unterst&uuml;tzt Visual Studio Sie mit IntelliSense.<\/p>\n<h2>Absteigende Sortierung<\/h2>\n<p>Unter SQL haben Sie f&uuml;r eine absteigende Sortierung das Schl&uuml;sselwort <b>DESC <\/b>hinten angef&uuml;gt (<b>ORDER BY Nachname DESC<\/b>). Unter LINQ to Entities verwenden Sie bei der Methodensyntax einfach eine andere Methode (<b>OrderByDescending<\/b>):<\/p>\n<pre>var kunden = \r\ncontext.Kunden.OrderByDescending(d =&gt; d.Nachname);<\/pre>\n<p>Bei der Abfragensyntax f&uuml;gen Sie &auml;hnlich wie bei SQL ein Schl&uuml;sselwort hinzu, hier <b>descending<\/b>:<\/p>\n<pre>var kunden = \r\nfrom d in context.Kunden \r\norderby d.Nachname descending \r\nselect d;<\/pre>\n<h2>Kunden nach bestimmten Kriterien ausgeben<\/h2>\n<p>Nun steigern wir den Schwierigkeitsgrad und wollen nur bestimmten Datens&auml;tze der Tabelle <b>Kunden <\/b>als Objekt ermitteln und durchlaufen. Unter Access\/VBA brauchen wir dazu nur die <b>SELECT<\/b>-Anweisung in der <b>OpenRecordset<\/b>-Methode zu &auml;ndern. Unter C#\/LINQ to Entities ist es auch nicht viel komplizierter &#8211; genau genommen haben Sie die Grundlagen dazu schon oben mit der Sortierung kennen gelernt.<\/p>\n<p>Wenn Sie beispielsweise den Kunden ermitteln wollen, dessen Eigenschaft <b>Nachname <\/b>den Wert <b>Minhorst <\/b>enth&auml;lt, formulieren Sie die Abfrage in der Methodensyntax wie folgt (siehe Methode <b>KundeMitNachname_Methodensyntax<\/b>).<\/p>\n<p>Sie verwenden also die <b>Where<\/b>-Methode statt der <b>OrderBy<\/b>-Methode:<\/p>\n<pre>var kunden = \r\ncontext.Kunden.Where(d =&gt; d.Nachname == \"Minhorst\");<\/pre>\n<p>In der Abfragensyntax erledigen Sie die Aufgabe mit dieser Zeile (siehe Methode <b>KundeMitNachname_Abfragesyntax<\/b>). Hier kommt also das <b>where<\/b>-Schl&uuml;sselwort mit dem Vergleichskriterium hinzu:<\/p>\n<pre>var kunden = \r\nfrom d in context.Kunden \r\nwhere d.Nachname == \"Minhorst\" \r\nselect d;<\/pre>\n<h2>Platzhalter<\/h2>\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\/55000048\/\">\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\/55000048?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\t\t\t\t\t<input type=\"hidden\" name=\"rcp_redirect\" value=\"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000048\/\"\/>\n\t\t\t\t\t\t\t\t<input type=\"hidden\" name=\"rcp_login_nonce\" value=\"876e5995cf\"\/>\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 vorangegangenen Ausgaben von DATENBANKENTWICKLER haben Sie bereits erfahren, wie Sie per ADO.NET auf die Daten der Tabellen einer Datenbank zugreifen. Nun nutzen wir nicht mehr direkt ADO.NET, sondern das Entity Framework als Datenlieferant, welches eine ganz andere Art des Zugriffs erm&ouml;glicht. Dieser Artikel zeigt, wie Sie per C#-Konsolenanwendung auf die per Entity Data Model bereitgestellten Daten zugreifen.<\/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":[662016,66042016,44000008,44000021,44000027,44000033],"tags":[],"yst_prominent_words":[],"class_list":["post-55000048","post","type-post","status-publish","format-standard","hentry","category-662016","category-66042016","category-Datenzugriffstechnik","category-Entity_Framework","category-Excel_programmieren","category-Visual_Basic_Programmierung"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000048","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=55000048"}],"version-history":[{"count":0,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/posts\/55000048\/revisions"}],"wp:attachment":[{"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/media?parent=55000048"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/categories?post=55000048"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/tags?post=55000048"},{"taxonomy":"yst_prominent_words","embeddable":true,"href":"https:\/\/vbentwickler.de\/data\/wp\/v2\/yst_prominent_words?post=55000048"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}