Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
ExecuteStoreQuery in eine dynamische Liste
m.grauber
myCSharp.de - Member



Dabei seit:
Beiträge: 345

Themenstarter:

ExecuteStoreQuery in eine dynamische Liste

beantworten | zitieren | melden

SQL-Server 2008, EntityFramework, VS2015

Hallo!

Bei einem ähnlichen Thema hatte ich bereits schon einmal nachgefragt: "[erledigt] Entity Framework - Nur einzelne Spalten mit CreateQuery auslesen" und scheinbar ist das nur per ExecuteStoreQuery möglich.

Da ich nun einen ExecuteStoreQuery ausführe und mir die Felder je nach Abfrage aus verschiedenen Tabellen hole und zusammenführe, muss es doch möglich sein, diese in eine ganz normale Liste mit den richtigen Feldnamen und Feldtypen zu überführen:


ExecuteStoreQuery<dynamic>("SELECT ...").ToList()
ExecuteStoreQuery<dynamic>("SELECT ...").ToList<dynamic>()

...liefern leider nur immer Listen mit Object-Typen.

Auch <List>, <List<dynamic>, <IENumerable<dynamic>> funktionieren nicht.

teils erhalte ich die Fehlermeldung:
Fehler
Der Ergebnistyp 'System.Collections.Generic.IEnumerable`1[System.Object]' darf nicht abstrakt sein und muss einen Standardkonstruktor enthalten.

Ich benötige aber eine Liste mit den richtigen Feldnamen und Feldtypen wie sie mir z. B der folgende Linq-Befehl zurückgibt:


var Liste = (from p in ... select new {Kunde.ID, Kunde.Name}).ToList()

Dies liefert nämlich eine "System.Collections.Generic.List`1[[<>f__AnonymousType8`7[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, ...", die ich weiter nutzen kann.

Auch das half mir nicht weiter:
[gelöst] Generics: Abstrakte Klassen und IEnumerable

Kann mir jemand als Ostergeschenk sagen, wie es richtig gemacht wird?

Dankesehr und schöne Ostern!
Mfg
Michael

PS: Ich stelle nur Fragen, wenn ich in Büchern, im Web und in Foren nichts gefunden habe. Dumme Fragen bitte ich zu entschuldigen!

:] VISUAL STUDIO 2017 + .NET FRAMEWORK 4.5 + SQL-Server 2012 :]
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15816
Herkunft: BW

beantworten | zitieren | melden

Dir ist schon bewusst, dass dieser Umsetzungsversuch ist, das sehr fehleranfällig ist und weswegen Sprachen wie C# eben streng typisiert sind?
Kein Mensch ausser der, der diese Klasse schreibt weiß, was sie an Daten liefert. Das ist nicht überschau oder ordentlich testbar.

Richtig gemacht wird es mit entsprechenden Klassen, die Dein Resultat als Typ repräsentieren.
private Nachricht | Beiträge des Benutzers
m.grauber
myCSharp.de - Member



Dabei seit:
Beiträge: 345

Themenstarter:

beantworten | zitieren | melden

Dankeschön für die Antwort.

Ja, das ist mir vollkommen klar. Aber je nachdem was ein Benutzer im laufenden Programm auswählt sollen unterschiedliche Spalten mit unterschiedlichen Typen zurückgeliefert werden.

Ich handle das Ergebnis dann schon richtig.

Kannst Du mir sagen, wie die richtige Syntax dafür lautet?

Danke
Mfg
Michael

PS: Ich stelle nur Fragen, wenn ich in Büchern, im Web und in Foren nichts gefunden habe. Dumme Fragen bitte ich zu entschuldigen!

:] VISUAL STUDIO 2017 + .NET FRAMEWORK 4.5 + SQL-Server 2012 :]
private Nachricht | Beiträge des Benutzers
T-Virus
myCSharp.de - Member



Dabei seit:
Beiträge: 1834
Herkunft: Nordhausen, Nörten-Hardenberg

beantworten | zitieren | melden

@m.grauber
Dann nimm lieber ein DataTable.
Dort hast du dann eine Tabelle und kannst dort über den Column Namen bei den jeweiligen Rows die Daten auslesen.
Solche Konstrukte wie List<Object> oder andere Späße gehören in die Tonne.

Nachtrag:
Wenn du die Liste umbedingt brauchst, solltest du jedes Ergebnis auf eine eigene Klasse mappen.
Alternativ, wenn du auf die selbe Tabelle/n bei den Abfragen zugreifst muss du nur eine Klasse anlegen und dann die entsprechenden Eigenschaften auslesen/verarbeiten.

Hier kennt aber keinen Code weshalb es schwierig ist zu wissen wie man dies optimal lösen kann.
Im Worst Case musst du eben pro Methode dann eine eigene Klasse schreiben, was aber recht aufwändig aber dafür eben sauber wäre.

T-Virus
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von T-Virus am .
Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.
private Nachricht | Beiträge des Benutzers
m.grauber
myCSharp.de - Member



Dabei seit:
Beiträge: 345

Themenstarter:

beantworten | zitieren | melden

Hallo T-Virus!

Danke für die Info!

Das Mappen einer eigenen Klasse ist nicht möglich, da erst der Anwender bestimmt, welche Spalten benötigt werden und diese aus verschiedenen Tabellen kommen können. Das wären also unendlich viele Klassen in unendlichen Kombinationen. Auch die Where-Klausel könnte dynamisch sein.

Folgendes zu DataTable habe ich gefunden:
"As the question/answer you linked to tells you, ExecuteStoreQuery returns entities - it cannot return a DataTable."
http://stackoverflow.com/questions/19796078/executestorequery-entityframework

Ist dort auch nur über eine bekannte Entität <MyEntity> gemacht worden.

Da der Code danach bereits steht und auf die Liste zugreift, tu ich mir schwer, etwas über die Columns auszulesen und dann in eine Liste einer Klasse zu schreiben, die ich erst zur Laufzeit(!) erzeugen müsste.

Ich werd's jetzt mal mit DynamicLinq versuchen.

Evtl. hat ja noch jemand einen Tipp (Abt?) oder Microsoft erweitert mal schnell C#, weil ich sicher nicht der einzige User bin, der so etwas braucht
Mfg
Michael

PS: Ich stelle nur Fragen, wenn ich in Büchern, im Web und in Foren nichts gefunden habe. Dumme Fragen bitte ich zu entschuldigen!

:] VISUAL STUDIO 2017 + .NET FRAMEWORK 4.5 + SQL-Server 2012 :]
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15816
Herkunft: BW

beantworten | zitieren | melden

Du versuchst etwas, für das eine typisierte Sprache nicht gedacht ist.
Ist wie Traktor-Fahren bei der Formel 1: sowas macht man nicht.
private Nachricht | Beiträge des Benutzers
t0ms3n
myCSharp.de - Member



Dabei seit:
Beiträge: 319

beantworten | zitieren | melden

Zitat von m.grauber
"As the question/answer you linked to tells you, ExecuteStoreQuery returns entities - it cannot return a DataTable."

Es zwingt dich ja niemand für diese Verhalten das EntityFramework zu nutzen.
private Nachricht | Beiträge des Benutzers
m.grauber
myCSharp.de - Member



Dabei seit:
Beiträge: 345

Themenstarter:

beantworten | zitieren | melden

Wenn ich andererseits nun doch verschiedene vorgegebene Klassen nutze: Z.B. Klasse1, Klasse2 könnte ich auch schon viel erreichen mit:

List<Klasse1> Liste1
List<Klasse2> Liste2

aber leider kann ich sie nicht strongly typed über einen immer gleichen Namen ansprechen. Ich hätte aber dann gerne das:


List<???> MeineListe = null;

if (i==1)
  MeineListe=Liste1
else
  MeineListe=Liste2

In jedem Fall möchte ich über "MeineListe" auf die Liste zugreifen, wobei sie je nach Bedarf andere Felder aufweist.

Wie macht man so etwas?
Mfg
Michael

PS: Ich stelle nur Fragen, wenn ich in Büchern, im Web und in Foren nichts gefunden habe. Dumme Fragen bitte ich zu entschuldigen!

:] VISUAL STUDIO 2017 + .NET FRAMEWORK 4.5 + SQL-Server 2012 :]
private Nachricht | Beiträge des Benutzers
t0ms3n
myCSharp.de - Member



Dabei seit:
Beiträge: 319

beantworten | zitieren | melden

Indem Du sie dann entsprechend castest.
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15816
Herkunft: BW

beantworten | zitieren | melden

Beide Klassen brauchen ein gemeinsames Interface, dann kannst Du mit List<Interface> arbeiten.
Ansonsten - auch hier - nicht Sinn einer typisierten Sprache.

Weisst Du überhaupt, dass C# eine typisierte Sprache ist? Und dass man so, wie Du arbeitet, eher - sorry - pfuscht?
Irgendwie hören sich Deine Wünsche und "Ideen" ehrlich gesagt nicht ganz so an ;-)
private Nachricht | Beiträge des Benutzers
T-Virus
myCSharp.de - Member



Dabei seit:
Beiträge: 1834
Herkunft: Nordhausen, Nörten-Hardenberg

beantworten | zitieren | melden

Bei dem was du vor hast, ist das Entity Framework der falsche Ansatz.
Wenn es "dynamisch" sein muss, dann lad die Daten direkt in ein DataTable.
Dieses ist dann relativ dynamisch, da die Spalten im DataTable denen aus der SQL Anweisung entsprechen.

Einen anderen/sinnvolleren Ansatz kann ich dir auf die schnelle nicht geben.
Aber mit Entity Framework bist du mit dieser Umsetzung relativ falsch.
Falls dir das DataTable zu fest wird, je nach Datenmenge kann dies deinen RAM schnell wegfressen, müsstest du ggf. was eigenes bauen.
Hier musst du dir dann eine eigene Container Klasse suchen/bauen die dann ähnlich wie das DataTable arbeitet.

T-Virus
Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.
private Nachricht | Beiträge des Benutzers
m.grauber
myCSharp.de - Member



Dabei seit:
Beiträge: 345

Themenstarter:

beantworten | zitieren | melden

Entschuldige Abt!

Deiner ersten Antwort entnahm ich, dass es "sehr fehleranfällig" sei, aber ich habe nicht daraus gelesen, dass es nicht möglich ist.

Das es eine typisierte Sprache ist, ist klar.

Aber wer kann sich heraussuchen, welche Projekte er übernimmt und mit welcher Technologie dort bereits gearbeitet wird? Abgesehen davon ist das EntityFramework eine sehr gute und schnell umzusetzende Sache!

Wenn bereits die Funktionalität zum Verbindungsauf/Abbau und die Zugriffe über das EF implementiert ist, versuche ich diese natürlich zu nutzen, statt den Aufbau - mit all seinen Facetten und teils geloggten Einträgen in der DB - in einer anderen Technologie nur für diese eine Abfrage nachzubauen.

Wenn nun die Anforderung kommt, so etwas dynamisches zu ermöglichen, sage ich sicher nicht, dass ich dafür nun erst einmal für das gesamte Projekt eine andere Technologie benötige und alles neu programmieren muss.

Ich besitze Jahrzehnte Erfahrung in der Softwareentwicklung unter verschiedensten Entwicklungsumgebungen und DBMS. Sicher derzeit noch nicht so viel in C#.

Wenn ein Linq-Befehl dies problemlos in eine anonyme Liste ermöglicht, aber ein ExecuteStoreQuery nicht, muss Microsoft doch etwas vergessen haben?

Da andererseits bei Linq der Teilaspekt DynamicLinq fehlt, kann man vielfach im Internet lesen - Das sind nicht alles Laien.


Vielen Dank für den Tipp mit dem Interface, ich habe es ebenfalls schon an anderen Stellen genutzt, bin aber hier nicht auf diese Idee gekommen!


Das mit dem "pfuschen" finde ich daher nicht freundlich.

Wenn Microsoft wieder neue Technologien herausbringt, müssen wir uns alle auf andere Entwicklungsumgebungen umstellen und sind dann alle erst einmal Laien.
Mfg
Michael

PS: Ich stelle nur Fragen, wenn ich in Büchern, im Web und in Foren nichts gefunden habe. Dumme Fragen bitte ich zu entschuldigen!

:] VISUAL STUDIO 2017 + .NET FRAMEWORK 4.5 + SQL-Server 2012 :]
private Nachricht | Beiträge des Benutzers
m.grauber
myCSharp.de - Member



Dabei seit:
Beiträge: 345

Themenstarter:

beantworten | zitieren | melden

Hallo T-Virus!

Danke auch Dir für die tolle Hilfe! Ich werde es nun erst einmal mit einer Schnittstelle realiseren, da

Wenn bereits die Funktionalität zum Verbindungsauf/Abbau und die Zugriffe über das EF implementiert ist, versuche ich diese natürlich zu nutzen, statt den Aufbau - mit all seinen Facetten und teils geloggten Einträgen in der DB - in einer anderen Technologie nur für diese eine Abfrage nachzubauen.

Sollte ich es noch dynamischer benötigen, muss ich dann eben wirklich anders zugreifen.

Nochmals vielen Dank an alle!
Mfg
Michael

PS: Ich stelle nur Fragen, wenn ich in Büchern, im Web und in Foren nichts gefunden habe. Dumme Fragen bitte ich zu entschuldigen!

:] VISUAL STUDIO 2017 + .NET FRAMEWORK 4.5 + SQL-Server 2012 :]
private Nachricht | Beiträge des Benutzers
t0ms3n
myCSharp.de - Member



Dabei seit:
Beiträge: 319

beantworten | zitieren | melden

Zitat von m.grauber
Wenn bereits die Funktionalität zum Verbindungsauf/Abbau und die Zugriffe über das EF implementiert ist, versuche ich diese natürlich zu nutzen, statt den Aufbau - mit all seinen Facetten und teils geloggten Einträgen in der DB - in einer anderen Technologie nur für diese eine Abfrage nachzubauen.

Das war auch gar nicht der Vorschlag. Es sollte lediglich für diesen einen Anwendungsfall eine andere (zusätzliche) Technologie genutzt werden.
private Nachricht | Beiträge des Benutzers
T-Virus
myCSharp.de - Member



Dabei seit:
Beiträge: 1834
Herkunft: Nordhausen, Nörten-Hardenberg

beantworten | zitieren | melden

@m.grauber
Niemand will von dir, das du jetzt das gesamte EF ersetzen sollst.
Es geht eben nur darum, in diesem einen Fall in dem die Daten dynamisch sein sollen, über die Basis Typen zuarbeiten.
Also z.B. SqlConnection, SqlDataAdapter etc.

Microsoft hat das EF dazu entwickelt, sowie alle ORMs, um eben Entitäten direkt auf Klassen zu mappen.
Dies kann aber auch nur funktionieren, wenn die Entität ein fix Schema hat.
Und C# macht dir dies wegen der starken Typisierung nicht einfacher.
Aber dann setzt du mit dem EF auf das flasche Pferd.

Hier kannst du dir eben nur durch eine Umsetzung mit einem DataTable helfen.
Oder du musst eben das Mapping mit einem eigenen Datentypen z.B. über einen DataReader erledigen.
Dann brauchst du eben einen Container, der das DataTable nachbildet.

Ob du 10 Jahre oder mehr Erfahrung hast, bringt dich bei der Lösung des Problems nicht weiter.
Ist zwar gut zu wissen, wenn man es mit erfahrenen Entwicklern zu tun hat, aber man muss dann auch offen für andere Möglichkeiten sein.
Sich hier auf EF zu versteifen, wird dir bei der Lösung des Problems nicht helfen.
Entsprechend solltest du dich an den Gedanken gewöhnen, dass für eine dynamische Umsetzung EF der flasche Ansatz ist.

T-Virus
Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.
private Nachricht | Beiträge des Benutzers