Hypercell ein ] Hypercell aus ] Zeige Navigation ] Verstecke Navigation ]
c++.de  
   

Die mobilen Seiten von c++.de:
http://m.c-plusplus.de
Infos hier [BETA]

  
c++.de :: C# und .NET ::  Datasource an List<T> binden     Zeige alle Beiträge auf einer Seite Auf Beitrag antworten
Autor Nachricht
Sonnenlichtfee
Unregistrierter




Beitrag Sonnenlichtfee Unregistrierter 11:13:50 28.03.2012   Titel:   Datasource an List<T> binden            Zitieren

Hallo,

so einigermaßen hat das mit dem Entity Framework geklappt, so dann ich darüber nun versuche meine Abfragen laufen zu lassen.

Nun stehe ich aber schon vor einem Problem - wie binde ich meine Daten an ein List<T>?

Gut, ich könnte einfach so machen - aber das möchte ich nicht:
C#:
...
var neuBefund= from b in context.tabellebefunde
                            orderby b.name
                            select b;
 
ComboBox1.DataSource = neuBefund;
...


Meine Vorstellung ist, dass ich der Methode einen Rückgabewert vom Typ IEnumerable<Befund> gebe. Folgendes habe ich versucht:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static IEnumerable<Befund> HoleWerteAusDB()
        {
            using (dbEntities context = new dbEntities())
            {
                List<Befund> listeBefund = new List<Befund>();
                listeBefund = from b in context.tabellebefunde
                               orderby b.name
                               select b;
                //Anweisung von oben geht so nicht
                //hier komme ich nicht weiter
                //listeBefund.Add( ... );
                                       
                return listeBefund;
            }
        }


Folgende Fehlermeldung
Zitat:

Der Typ "System.Linq.IOrderedQueryable<Test.tabellebefunde>" kann nicht implizit in "System.Collections.Generic.List<Test.Classes.Befund>" konvertiert werden.


Hoffe ihr habt mein Problem verstanden. Würde mich über Eure Antworten freuen! Danke!
deleted_2013_01_05
Mitglied

Benutzerprofil
Anmeldungsdatum: 14.06.2001
Beiträge: 1795
Beitrag deleted_2013_01_05 Mitglied 11:40:28 28.03.2012   Titel:              Zitieren

Du kannst ToList() auf den Linq-Ausdruck anwenden.

http://msdn.microsoft.com/de-de/library/bb342261.aspx

Das hat aber zur Folge, dass keine "Deferred Execution" mehr stattfindet, sondern die Abfrage auf einen Schlag durchgeführt wird. Das kann u.U. unerwünscht sein.
Th69
Mitglied

Benutzerprofil
Anmeldungsdatum: 25.03.2008
Beiträge: 2586
Beitrag Th69 Mitglied 11:59:31 28.03.2012   Titel:              Zitieren

Ansonsten mit "yield return" (innerhalb einer foreach-Schleife) arbeiten (damit der DBContext nicht vorher disposed wird).

C#:
1
2
3
4
5
6
7
8
9
10
11
12
public static IEnumerable<Befund> HoleWerteAusDB()
{
    using (DbEntities context = new DbEntities())
    {
        listeBefund = from b in context.tabellebefunde
                      orderby b.name
                      select b;
 
        foreach (var entry in listBefund)
            yield return entry;
    }
}


P.S. Die Klasse sollte "DbEntities" heißen (entsprechend den Microsoft Naming Conventions), daher habe ich den Code so angepaßt!
Sonnenlichtfee
Unregistrierter




Beitrag Sonnenlichtfee Unregistrierter 12:09:02 28.03.2012   Titel:              Zitieren

Danke Euch beiden ...

Leider habe ich in beidne Fällen Probleme mit der Umwandlung

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public static IEnumerable<Befund> HoleWerteAusDB()
        {
            using (DbEntities context = new DbEntities())
            {
                List<Befund> liste = new List<Befund>();
 
                var query = from b in context.tabellebefunde
                             select b.Name;
 
 
                liste = query.Select(befund=> befund.ToString()).ToList();
 
                return liste;
 
            }
 
        }

Zitat:

Eine implizite Konvertierung vom Typ "System.Collections.Generic.List<string>" in "System.Collections.Generic.List<Test.Klassen.Befund>" ist nicht möglich.





C#:
1
2
3
4
5
6
7
8
9
10
11
        public static IEnumerable<Befund> HoleWerteAusDB()
        {
            using (DbEntities context = new DbEntities())
            {
                var liste = from b in context.tabellebefunde
                             select b.Name;
 
                foreach (var entry in liste)
                    yield return entry;
            }
        }

Zitat:

Eine implizite Konvertierung vom Typ "Test.tabellebefund" in "Test.Klassen.Befund" ist nicht möglich.


Fehlt beides mal die Umwandlung, oder ist ein anderer Fehler drin? :confused:
Marc-O
Mitglied

Benutzerprofil
Anmeldungsdatum: 02.04.2008
Beiträge: 211
Beitrag Marc-O Mitglied 13:15:57 28.03.2012   Titel:              Zitieren

Sonnenlichtfee schrieb:
Danke Euch beiden ...

Leider habe ich in beidne Fällen Probleme mit der Umwandlung

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public static IEnumerable<Befund> HoleWerteAusDB()
        {
            using (DbEntities context = new DbEntities())
            {
                List<Befund> liste = new List<Befund>();
 
                var query = from b in context.tabellebefunde
                             select b.Name;
 
 
                liste = query.Select(befund=> befund.ToString()).ToList();
 
                return liste;
 
            }
 
        }

Zitat:

Eine implizite Konvertierung vom Typ "System.Collections.Generic.List<string>" in "System.Collections.Generic.List<Test.Klassen.Befund>" ist nicht möglich.


Hier wird mit der Funktion "Select()" vor dem ToList() "nur" ein String ermittelt, also kommt auch eine String-Liste heraus, und du willst aber eine Befund-Liste zurückgeben, dann lass die komplette Select()-Funktion weg.


Sonnenlichtfee schrieb:

C#:
1
2
3
4
5
6
7
8
9
10
11
        public static IEnumerable<Befund> HoleWerteAusDB()
        {
            using (DbEntities context = new DbEntities())
            {
                var liste = from b in context.tabellebefunde
                             select b.Name;
 
                foreach (var entry in liste)
                    yield return entry;
            }
        }

Zitat:

Eine implizite Konvertierung vom Typ "Test.tabellebefund" in "Test.Klassen.Befund" ist nicht möglich.


Fehlt beides mal die Umwandlung, oder ist ein anderer Fehler drin? :confused:

Hier ist es das gleiche Problem, im from...select b.Name wird definiert, das nur der Name des Objekte zurückgegeben wird, welcher warscheinlich ein String ist, dadurch wird beim yield return auch nur ein String zurück gegeben und nicht das befund-Objekt. hier einfach das "select b.Name" durch "select b" tauschen.

Mfg Marco

_________________
CodeBlocks Nightly
MinGW64 (Windows) / gcc (Linux)
Alles was so anfällt blog
Sonnenlichtfee
Unregistrierter




Beitrag Sonnenlichtfee Unregistrierter 13:28:49 28.03.2012   Titel:              Zitieren

Wie Du vorgeschlagen hast, hab ich es auch schon probiert (also ohne .Select()) - wieder selbes Problem
C#:
liste = query.ToList();


Auch wenn ich nur
C#:
select b;
schreibe, hab ich wieder ein Konvertierungsproblem.

Meine Liste passt soweit, d.h. sie gibt Werte zurück (hab sie direkt als DataSource an die Combobox gehängt - ohne Probleme).
Marc-O
Mitglied

Benutzerprofil
Anmeldungsdatum: 02.04.2008
Beiträge: 211
Beitrag Marc-O Mitglied 13:39:40 28.03.2012   Titel:              Zitieren

Ich hoffe jetzt mal, das die Klasse Befund auch aus dem Entity-Framework kommt, und nicht eine Klasse, neu definierte an einer anderen Stelle ist.

Ansonst könntest du bitte nochmal die genaue Fehlermeldung posten?

MfG Marco

_________________
CodeBlocks Nightly
MinGW64 (Windows) / gcc (Linux)
Alles was so anfällt blog
Sonnenlichtfee
Unregistrierter




Beitrag Sonnenlichtfee Unregistrierter 14:32:46 28.03.2012   Titel:              Zitieren

Zitat:
Ich hoffe jetzt mal, das die Klasse Befund auch aus dem Entity-Framework kommt, und nicht eine Klasse, neu definierte an einer anderen Stelle ist.

Genau das war das Problem! :( Danke für den Hinweis! Jetzt klappts!
Sonnenlichtfee
Unregistrierter




Beitrag Sonnenlichtfee Unregistrierter 16:08:30 28.03.2012   Titel:              Zitieren

Was muss ich bei einer Methode als Rückgabetyp angeben, um damit an anderer Stelle einen GridView befüllen zu können? Kann man das pauschal sagen? Oder gibt es mehrere Möglichkeiten?

Die Daten dafür sollen ebenfalls übers Entity Framework mittels Linq (select und join) abgefragt werden.
Abfrage steht soweit auch schon
C#:
var joinQuery = from b in context.tabellebefund
                join w in context.tabellewerte on b.nummer equals w.befundNr
                select new { w.WertHD, b.Nummer };
Sonnenlichtfee
Unregistrierter




Beitrag Sonnenlichtfee Unregistrierter 11:19:39 29.03.2012   Titel:              Zitieren

Die beiden gewünschten Werte kann ich nun auslesen (MessageBox).

Wie kann ich diese (einmal string einmal int32) so "speichern" oder übergeben, dass ich mit diesen ein GridView füllen kann?
Th69
Mitglied

Benutzerprofil
Anmeldungsdatum: 25.03.2008
Beiträge: 2586
Beitrag Th69 Mitglied 13:19:30 29.03.2012   Titel:              Zitieren

Anonyme Klassen kannst du nicht über Methodengrenzen hinweg zurückgeben, d.h. du mußt dir eine Klasse (XXX) definieren und dann entsprechend IEnumerable<XXX> zurückgeben.
Dravere
Moderator

Benutzerprofil
Anmeldungsdatum: 13.06.2005
Beiträge: 8169
Beitrag Dravere Moderator 14:01:04 29.03.2012   Titel:              Zitieren

Th69 schrieb:
Anonyme Klassen kannst du nicht über Methodengrenzen hinweg zurückgeben, d.h. du mußt dir eine Klasse (XXX) definieren und dann entsprechend IEnumerable<XXX> zurückgeben.

Das ist so nicht ganz korrekt. Es gibt seit C# 4.0 das Schlüsselwort dynamic. Dieses kann man auch als Rückgabewert oder als Generictype Parameter verwenden.
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
using System;
using System.Collections.Generic;

 
public class Program
{
  public static IEnumerable<dynamic> Test()
  {
    yield return new
    {
      Test = "Hello"
    };
  }
 
  public static void Main(string[] args)
  {
    foreach(var obj in Test())
    {
      Console.WriteLine(obj.Test);
    }
  }
}

Man sollte sich allerdings bewusst sein, dass sich dies negativ auf die Performance auswirken kann. Ist somit mit Vorsicht zu geniessen ;)

Grüssli

_________________
Danke für die Hilfe, Antwort oder Meinung!
C++: Std-Lib Referenz
C# .Net: MSDN kennt die Antwort
Sonnenlichtfee
Unregistrierter




Beitrag Sonnenlichtfee Unregistrierter 15:40:43 29.03.2012   Titel:              Zitieren

Danke mit dem Hinweis mit dynamic werde ich morgen mal testen.

Beim Googeln bin ich auf CopyToDataTable gestossen.
Damit sollte ich doch die Linq Abfrage einer DataTable übergeben können und diese dann an ein GridView binden können?!

Dazu habe ich gesehen, dass System.Data.DataSetExtension eingefügt werden muss.
Den Verweis dazu kann ich auch unter Verweise in meinem Projekt sehen, über using kann ich es aber nicht einbinden. An was kann das liegen?
Sonnenlichtfee
Unregistrierter




Beitrag Sonnenlichtfee Unregistrierter 13:13:40 30.03.2012   Titel:              Zitieren

Edit by Dravere:
Der folgende Teilbeitrag wurde bei einer Abtrennung ebenfalls entfernt
Dravere schrieb:
@Sonnenlichtfee,
Hast du die richtige Version eingebunden? Zum Teil gibt es Probleme, wenn man die falsche DLL Version von System.Data.DataSetExtension einbindet. Also zum Beispiel die Version für .Net 3.5 in einem .Net 4 Projekt probiert zu verwenden.

Edit End

--------------------------------------

Auf dem PC wird .Net 4 verwendet.
Im VS wird beim Verweis die Version v4.0.30319 angegeben - eine andere kann ich auch nicht finden.
Dennoch kann ich using System.Data.DataDataSetExtension; nicht einbinden.

Gibts dafür noch andere Voraussetzungen, dass es eingebunden werden kann?


Zuletzt bearbeitet von Dravere am 22:11:51 30.03.2012, insgesamt 1-mal bearbeitet
Dravere
Moderator

Benutzerprofil
Anmeldungsdatum: 13.06.2005
Beiträge: 8169
Beitrag Dravere Moderator 14:06:03 30.03.2012   Titel:              Zitieren

@Sonnenlichtfee,
Oh, moment, moment, mein Fehler ...

Die System.Data.DataSetExtension.dll legt ihre Objekte ja im System.Data Namensraum ab. Es gibt keinen System.Data.DataSetExtension Namensraum! Ich arbeite zu wenig mit DataSet zusammen, hatte ich gerade ganz vergessen :)

Siehe zum Beispiel:
http://msdn.microsoft.com ....... .datatableextensions.aspx
Zitat:
Namespace: System.Data
Assembly: System.Data.DataSetExtensions (in System.Data.DataSetExtensions.dll)

Grüssli

_________________
Danke für die Hilfe, Antwort oder Meinung!
C++: Std-Lib Referenz
C# .Net: MSDN kennt die Antwort
Sonnenlichtfee
Unregistrierter




Beitrag Sonnenlichtfee Unregistrierter 14:46:03 30.03.2012   Titel:              Zitieren

@Dravere
Jetzt hab ich zumindest das eigentlich Problem gefunden - denke ich zumindest

Für die Klasse aus dem Entity Framework (Befund) gibt es keine CopyToDataTable() Methode. Zumindest wird dies so nicht angeboten.
Müsste ich diese dann selbst schreiben?

C#:
IEnumerable<Befund> test =
                    from i in context.tblbefund.AsEnumerable()
                    select i;
 
    DataTable dt = test.CopyToDataTable();
    return dt;




Denn folgender Aufruf kennt die Methode dann doch (allerdings gibt es hier dann wieder ein Konvertierungsproblem)
C#:
IEnumerable<DataRow> test =
                    from i in context.tblbefund.AsEnumerable()
                    select i;
 
    DataTable dt = test.CopyToDataTable();
    return dt;


Falls selber schreiben, an was kann ich mich da orientieren, wie das aufgebaut sein soll?
Dravere
Moderator

Benutzerprofil
Anmeldungsdatum: 13.06.2005
Beiträge: 8169
Beitrag Dravere Moderator 18:24:14 30.03.2012   Titel:              Zitieren

Das ganze wird langsam unübersichtlich...

Was willst du eigentlich erreichen? Du redest weiter vorne davon, dass du es an ein GridView binden möchtest. Reden wir hier von WPF?
Möchtest du also die Resultate, welche du erhälst, in einem WPF GridView einer ListView anzeigen lassen?

Grüssli

_________________
Danke für die Hilfe, Antwort oder Meinung!
C++: Std-Lib Referenz
C# .Net: MSDN kennt die Antwort
Sonnenlichtfee
Unregistrierter




Beitrag Sonnenlichtfee Unregistrierter 22:08:51 30.03.2012   Titel:              Zitieren

Ich möchte einen Rückgabewert erhalten, den ich übergeben kann und dann an ein DataGridView (WinForms) hängen kann.

Bisher habe ich dazu immer eine DataTable zurück gegeben und diese dann als DataSource an das GridView gehängt.
Th69
Mitglied

Benutzerprofil
Anmeldungsdatum: 25.03.2008
Beiträge: 2586
Beitrag Th69 Mitglied 11:07:48 31.03.2012   Titel:              Zitieren

An die DataGridView.DataSource-Eigenschaft kannst du doch auch direkt eine List<XXX> o.ä. dranhängen - es muß ja keine DataTable sein.
Also in deinem Code einfach
C++:
return test.ToList();

verwenden.
Sonnenlichtfee
Unregistrierter




Beitrag Sonnenlichtfee Unregistrierter 10:08:34 02.04.2012   Titel:              Zitieren

@Th69
Danke für den Tipp - so klappt es!

Wenn ich allerdings nur einzelne Spalten selektieren möchte, bekommme ich schon wieder ein Konvertierungsproblem angezeigt.

C#:
select new { i.Befund, i.Bezeichnung };


Kann mir vielleicht jemand eine gute Seite zu Linq sagen oder hat jemand einen Buchtipp für mich?! Denke die Grundlagen in diesem Bereich fehlen bei mir total ...
-..-
Unregistrierter




Beitrag -..- Unregistrierter 10:12:22 02.04.2012   Titel:              Zitieren

http://msdn.microsoft.com/en-us/library/bb397926.aspx
Sonnenlichtfee
Unregistrierter




Beitrag Sonnenlichtfee Unregistrierter 10:53:28 03.04.2012   Titel:              Zitieren

Da ich nun einige Mal Probleme mit Anonymous Type hatte, wollte ich nun mal fragen, ob der Lösungsansatz soweit korrekt ist - bzw. ein kleines Problem gibt es dabei auch noch.

Bei dieser Anweisung habe ich die Fehlermeldung bzgl. des anonymous types erhalten.
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public IEnumerable<Befund> GetBefundWithNames()
{
    using (dbEntities db = new dbEntities())
    {
      var result = from b in db.Befund
                   join n in db.Name on b.ID equals n.BefundID
                   select new
                          {
                              Befund = b.Bezeichnung,
                              Name = n.Name
                          };
 
      return result;
    }
}


Um das Problem zu lösen, hab ich eine extra Klasse erstellt
C#:
public class Befunde
{
    public Befund Bef { get; set; }
    public Name BName  { get; set; }
}


Und dann folgende Anweisung geschrieben
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public IEnumerable<Befunde> GetBefundWithNames()
{
    using (dbEntities db = new dbEntities())
    {
      var result = from b in db.Befund
                   join n in db.Name on b.ID equals n.BefundID
                   select new Befunde
                          {
                              Bef= b,
                              BName = n
                          };
 
      return result.ToList();
    }
}


Aufruf erfolgt mit
C#:
DataGridView1.DataSource = DB.GetBefundWithNames();


Erst mal die Frage, was haltet ihr grundsätzlich von der Lösung mit der eigenen Klasse? Ist das ein sauberer Lösungsansatz?

Wenn ich die Liste nun als DataSource an meinen GridView hängen möchte, werden anstatt der Daten leider nur ProjektName.Befund bzw. ProjektName.Name
angezeigt.
Wie kann ich bestimmen, was angezeigt werden soll?
Folgendes geht jedenfalls nicht
C#:
 Bef= b.Bezeichnung,
 BName = n.Name


Ich danke Euch!
Sonnenlichtfee
Unregistrierter




Beitrag Sonnenlichtfee Unregistrierter 11:58:46 03.04.2012   Titel:              Zitieren

Das mit dem richtigen Anzeigen der Daten hat sich geklärt:
C#:
public class Befunde
{
    public string Bef { get; set; }
    public string Name { get; set; }
}


Aber weiterhin die Frage: gutes oder schlechtes Vorgehen im Umgang mit anonymous Types?
Th69
Mitglied

Benutzerprofil
Anmeldungsdatum: 25.03.2008
Beiträge: 2586
Beitrag Th69 Mitglied 12:53:03 03.04.2012   Titel:              Zitieren

Was gefällt dir daran denn nicht? Außer der Variante mit dynamic (s. http://www.c-plusplus.de/forum/301608) gibt es wohl auch keinen eleganten Weg.
Du könntest zwar ein untypisiertes IEnumerable zurückgeben, jedoch verlierst du damit m.E. alle Vorzüge der modernen .NET-Entwicklung (zu .NET 1.x Zeiten war dies ja der einzige Weg, aber daher wurden ja auch ab .NET 2.0 generics eingeführt).
Sonnenlichtfee
Unregistrierter




Beitrag Sonnenlichtfee Unregistrierter 13:00:58 03.04.2012   Titel:              Zitieren

@Th69
Danke - wollte nur Eure Meinung dazu wissen! :)
Das mit dynamic werde ich mir aber trotzdem mal noch anschauen.
c++.de :: C# und .NET ::  Datasource an List<T> binden   Auf Beitrag antworten

Zeige alle Beiträge auf einer Seite




Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Sie können Beiträge in dieses Forum schreiben.
Sie können auf Beiträge in diesem Forum antworten.
Sie können Ihre Beiträge in diesem Forum nicht bearbeiten.
Sie können Ihre Beiträge in diesem Forum nicht löschen.
Sie können an Umfragen in diesem Forum nicht mitmachen.

Powered by phpBB © 2001, 2002 phpBB Group :: FI Theme

c++.de ist Teilnehmer des Partnerprogramms von Amazon Europe S.à.r.l. und Partner des Werbeprogramms, das zur Bereitstellung eines Mediums für Websites konzipiert wurde, mittels dessen durch die Platzierung von Werbeanzeigen und Links zu amazon.de Werbekostenerstattung verdient werden kann.

Die Vervielfältigung der auf den Seiten www.c-plusplus.de, www.c-plusplus.info und www.c-plusplus.net enthaltenen Informationen ohne eine schriftliche Genehmigung des Seitenbetreibers ist untersagt (vgl. §4 Urheberrechtsgesetz). Die Nutzung und Änderung der vorgestellten Strukturen und Verfahren in privaten und kommerziellen Softwareanwendungen ist ausdrücklich erlaubt, soweit keine Rechte Dritter verletzt werden. Der Seitenbetreiber übernimmt keine Gewähr für die Funktion einzelner Beiträge oder Programmfragmente, insbesondere übernimmt er keine Haftung für eventuelle aus dem Gebrauch entstehenden Folgeschäden.