Entwickler-Ecke
Datenbanken (inkl. ADO.NET) - Rückgabewert der Abfrage
Megatrash - So 22.03.15 10:33
Titel: Rückgabewert der Abfrage
Hallo,
ich habe gerade angefangen mich mit dem Entity Framework von Microsoft zu beschäftigen. In meinem aktuellen Projekt habe ich eine DLL, welche den Datenbankzugriff regeln soll.
Hier gibt es die folgende Funktion:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| private myDatabaseModelContainer db = new myDatabaseModelContainer();
public IEnumerable<Category> GetCategories() { var categories = (from c in db.Categories select new { c.Id, c.Name });
return categories.ToList(); } |
In dem eigentlichen Programm möchte ich das Ergebnis in einer WPF ListBox anzeigen lassen:
C#-Quelltext
1:
| myListBox.ItemsSource = currentDB.GetCategories(); |
Es werden jedoch keine Daten angezeigt.
Megatrash - So 22.03.15 12:45
Hallo,
vielen Dank für die schnelle Antwort. Leider habe ich nun so viel herumprobiert, dass ich immer wieder andere Meldungen herhalten habe. Ich habe in einem ersten Test folgendes gemacht:
C#-Quelltext
1: 2: 3: 4:
| var categories = (from ct in db.Categories select new { ct.Id, ct.Name });
myListBox.ItemsSource = categories.ToList(); |
Dies hat auch prima geklappt. Jetzt wollte ich gerne alle Abfragen der Applikation zentral in einer DLL hinterlegen und so vermeiden, dass ich diese immer wieder neu schreiben muss.
Gibt es evtl. irgendwo ein Beispiel?
Megatrash - So 22.03.15 13:08
weitere Infos:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37:
| public partial class MainWindow : Window { private myQueries q = new myQueries(); private myDatabaseModelContainer db = new myDatabaseModelContainer();
public MainWindow() { InitializeComponent(); }
private void Window_Loaded(object sender, RoutedEventArgs e) { var products = (from p in db.Products select new { p.Id, p.Name }); myListBox01.ItemsSource = products.ToList(); myListBox02.ItemsSource = q.GetProducts(); } }
public class myQueries { private myDatabaseModelContainer db = new myDatabaseModelContainer();
public IQueryable GetProducts() { var products = (from p in db.Products select new { p.Id, p.Name });
return products; } } |
Die ListBox01 wird entsprechend gefüllt. Für die ListBox02 kommt die folgende Fehlermeldung:
System.NotSupportedException wurde nicht behandelt.
HResult=-2146233067
Message=Die direkte Datenbindung an eine Speicherabfrage (DbSet, DbQuery, DbSqlQuery, DbRawSqlQuery) wird nicht unterstützt. Füllen Sie stattdessen ein 'DbSet' mit Daten, indem Sie z. B. 'Load' für 'DbSet' aufrufen, und nehmen Sie dann eine Bindung an lokale Daten vor. Bei WPF nehmen Sie eine Bindung an 'DbSet.Local' vor. Bei 'WinForms' nehmen Sie eine Bindung an 'DbSet.Local.ToBindingList()' vor. Bei ASP.NET WebForms können Sie eine Bindung an das Ergebnis des Aufrufs von 'ToList()' der Abfrage vornehmen oder die Modellbindung verwenden. Weitere Informationen finden Sie unter
http://go.microsoft.com/fwlink/?LinkId=389592.
Source=EntityFramework
StackTrace:
bei System.Data.Entity.Infrastructure.DbQuery`1.System.ComponentModel.IListSource.GetList()
...
Ralf Jansen - So 22.03.15 14:42
Hab da gerade auch nur einen allgemeinen Hinweis.
Es erscheint mir widersinnig wenn man versucht eine dezidierte Datenschicht aufzubauen, die man sogar in eine eigene Assembly auslagert, dieser eine Oberfläche zu geben die EF Verhalten exportiert. Heißt wo der Verwender wissen muss wie sich diese Schicht intern verhält, aka EF und z.B. dessen Lazy Loading, und auch noch anonyme Typen als object exportiert worüber der Verwender dann auch internes Wissen haben muss das die Oberfläche der Schicht nicht so einfach hergibt.
Da fand ich dein Codebeispiel im ersten Beitrag schon besser. Dort sehe ich nur das Problem das du versucht hast den anonymen Typ den die Abfrage liefert auf einen konkreten zu mappen. Ich hätte vermutet das das so nicht mal compiliert. :gruebel:
Wenn du mich fragst würde ich wieder zur Methodik des ersten Beitrags zurückkehren. Deiner Datenschicht wieder ein entsprechend eindeutiges Interface geben, das nur kontextfreie Interfaces, Listentypen und konkrete Datentypen transportiert und somit ohne internes Wissen über die Datenschicht beim Nutzer der Datenschicht auskommt.
Die Abfrage des erste Beitrags müsste dabei nur eher so aussehen.
C#-Quelltext
1: 2:
| var categories = (from c in db.Categories select new Category() { Id = c.Id, Name = c.Name }); |
Megatrash - So 22.03.15 14:55
Leider nein. :(
Es kommt dann die Meldung:
'System.Linq.IQueryable' enthält keine Definition für 'ToList', und es konnte keine Erweiterungsmethode 'ToList' gefunden werden, die ein erstes Argument vom Typ 'System.Linq.IQueryable' akzeptiert (Fehlt eine Using-Direktive oder ein Assemblyverweis?).
jfheins - So 22.03.15 16:58
Megatrash hat folgendes geschrieben : |
Es kommt dann die Meldung:
'System.Linq.IQueryable' enthält keine Definition für 'ToList', und es konnte keine Erweiterungsmethode 'ToList' gefunden werden, die ein erstes Argument vom Typ 'System.Linq.IQueryable' akzeptiert (Fehlt eine Using-Direktive oder ein Assemblyverweis?). |
Versuche mal, oben bei den Using-Direktiven, folgende hinzuzufügen:
Die Funktionen sind nur verfügbar, wenn man den passenden Namespace (durch
using) einbindet.
Megatrash - Mo 30.03.15 15:24
Vielen Dank für die Ratschläge. Aufgrund des Zeitdrucks habe ich mich entschieden bei dem aktuellen Projekt nicht das Entity Framework einzusetzen.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!