Autor Beitrag
Megatrash
Hält's aus hier
Beiträge: 10



BeitragVerfasst: So 22.03.15 10:33 
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:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
private myDatabaseModelContainer db = new myDatabaseModelContainer();

        /// <summary>
        /// Gibt alle in der Datenbank vorhandenen Produktkategorien zurück.
        /// </summary>
        /// <returns></returns>
        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:

ausblenden C#-Quelltext
1:
myListBox.ItemsSource = currentDB.GetCategories();					


Es werden jedoch keine Daten angezeigt.
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: So 22.03.15 11:57 
Hallo und :welcome:

was sagt denn der Debugger? Gibt die Methode eine gefüllte Liste zurück?

Und hast du denn bei der ListBox auch ein ItemTemplate angegeben (ansonsten wird nur die ToString()-Methode der zugewiesenen ItemsSource angezeigt (s.a. ListView, data binding and ItemTemplate).

Wenn du nur eine Spalte (z.B. Name) anzeigen möchtest, dann reicht es auch zusätzlich die DisplayMemberPath-Eigenschaft zu setzen.

PS: Generell kann ich dir die WPF Tutorial-Seite empfehlen.
Megatrash Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: 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:

ausblenden 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 Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: So 22.03.15 13:08 
weitere Infos:

ausblenden volle Höhe 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:
 /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    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 go.microsoft.com/fwlink/?LinkId=389592.
Source=EntityFramework
StackTrace:
bei System.Data.Entity.Infrastructure.DbQuery`1.System.ComponentModel.IListSource.GetList()
...
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: So 22.03.15 14:21 
Klappt es denn, wenn du
ausblenden C#-Quelltext
1:
myListBox02.ItemsSource = q.GetProducts().ToList();					
verwendest?

Das Stichwort bzgl. ToList() nennt sich "Materialisierung".

Evtl. müsstest du dann als Rückgabewert der Datenbankmethoden anstatt IEnumerable<Category> oder IQueryable dann IList<Category> verwenden (bzw. IList<Product>) - mit dem EF kenne ich mich leider nicht so aus.

Die beiden Beiträge
Data binding directly to a store query (DbSet, DbQuery, DbSqlQuery) is not supported Entity Framework 5
Data binding directly to a store query (DbSet, DbQuery, DbSqlQuery) is not supported
deuten aber auch beide in die selbe Richtung.
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4701
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: 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.

ausblenden C#-Quelltext
1:
2:
var categories = (from c in db.Categories
                  select new Category() { Id = c.Id, Name = c.Name });
Megatrash Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 918
Erhaltene Danke: 158

Win 10
VS 2013, VS2015
BeitragVerfasst: So 22.03.15 16:58 
user profile iconMegatrash hat folgendes geschrieben Zum zitierten Posting springen:

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:
ausblenden C#-Quelltext
1:
using System.Linq;					


Die Funktionen sind nur verfügbar, wenn man den passenden Namespace (durch using) einbindet.
Megatrash Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: 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.