Laden...

ExecuteStoreQuery in eine dynamische Liste

Erstellt von m.grauber vor 8 Jahren Letzter Beitrag vor 8 Jahren 4.783 Views
M
m.grauber Themenstarter:in
343 Beiträge seit 2010
vor 8 Jahren
ExecuteStoreQuery in eine dynamische Liste

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:

Fehlermeldung:
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.List1[[&lt;&gt;f__AnonymousType87[[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 :]

16.806 Beiträge seit 2008
vor 8 Jahren

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.

M
m.grauber Themenstarter:in
343 Beiträge seit 2010
vor 8 Jahren

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

T
2.219 Beiträge seit 2008
vor 8 Jahren

@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

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.

M
m.grauber Themenstarter:in
343 Beiträge seit 2010
vor 8 Jahren

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

16.806 Beiträge seit 2008
vor 8 Jahren

Du versuchst etwas, für das eine typisierte Sprache nicht gedacht ist.
Ist wie Traktor-Fahren bei der Formel 1: sowas macht man nicht.

T
314 Beiträge seit 2013
vor 8 Jahren

"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.

M
m.grauber Themenstarter:in
343 Beiträge seit 2010
vor 8 Jahren

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

T
314 Beiträge seit 2013
vor 8 Jahren

Indem Du sie dann entsprechend castest.

16.806 Beiträge seit 2008
vor 8 Jahren

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 😉

T
2.219 Beiträge seit 2008
vor 8 Jahren

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.

M
m.grauber Themenstarter:in
343 Beiträge seit 2010
vor 8 Jahren

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

M
m.grauber Themenstarter:in
343 Beiträge seit 2010
vor 8 Jahren

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

T
314 Beiträge seit 2013
vor 8 Jahren

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.

T
2.219 Beiträge seit 2008
vor 8 Jahren

@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.