Laden...

Linq to EF Join-Abfrage Auswahl aller Spalten möglich?

Erstellt von oehrle vor 13 Jahren Letzter Beitrag vor 13 Jahren 2.606 Views
O
oehrle Themenstarter:in
461 Beiträge seit 2009
vor 13 Jahren
Linq to EF Join-Abfrage Auswahl aller Spalten möglich?

verwendetes Datenbanksystem: <SQLEXPRESS 2008>

Hi, ich arbeite mich im moment in Linq to EF ein.
Habe schon einige Fehler geknackt, die einem Frischling so passieren.
Im moment bin ich an einer Abfrage mit Join. Die abfrage funktioniert auch. Nur möchte ich in der select new{} nicht alle Spalten der beiden Tabellen für die Ausgabe alle eingeben, sondern alle irgendwie mit einer Bezeichnung auswählen, wie bei SQL (Select * FROM _C1) als Besipiel. Geht das in Linq? Hintergund: in mnchen Tabellen sind 40 Spalten abgelegt, das ist dann mühsam.
Kann mir jemand helfen?


var v = from g in _c1
                    join p in _kopf on g.Bezeichnung equals p.Dateiname
                    select new {g,p};   // hier müßte sowas wie bei SQL select * geben

1.552 Beiträge seit 2010
vor 13 Jahren

Hallo oehrle,

Ich nehme mal an dass _kopf eine Liste in der aktuellen Klasse ist.


var v = from g in _c1 where g._kopf.Bezeichnung equals p.Dateiname select g;

zugreifen kannst du du dann über

v._kopf

Ich mach das aber immer direkt über die EntityCollection-Connection

from g in _conn.C1 where g.Kopf.Bezeichnung.....

Ich konnte leider nur erraten wie dein EF-Model aussieht, desswegen musst du etwas herum experimentiern

Gruß
Michael

Mein Blog
Meine WPF-Druckbibliothek: auf Wordpress, myCSharp

O
oehrle Themenstarter:in
461 Beiträge seit 2009
vor 13 Jahren
Funktioniert so nicht

Hallo, das funktioniert so nicht. Noch mal zu meiner Erklärung: Ich habe zwei Tabellen, die Tabelle _kopf und die Tabelle _c1
Die Tabelle _kopf hat eine Spalte die mit der Tabelle _c1 übereinstimmt. Es ist aber keine Fremdschlüsselbeziehung in der Datenbank angelegt. Ich möchte nun die alle Datensaätze der Tabelle _kopf, wo die Fremdschlüsselspalte identisch mit der Beziechnung in der Bezugspalte der Tabelle _c1 ist.

In SQL mach ich das über Join, oder über Where.

In Linq to EF kann man das auch über Join machen, hat aber den Nachteil das ich nicht weiß wie ich alle Spalten auf einen Schlag auswählen kann, da ich sonst bei
SELECT NEW{_kopf.xxx, _kopf.yyy, _c1.xxx, _c1.yyy .....) alles eintrgaen muß. Ich habe sehr viel Spalten und ich möchte dann diese Muster für andere Tabellen weiterverwenden. Gibts da keinen generellen BEfehl, der alle Spalten übernimmt????

1.552 Beiträge seit 2010
vor 13 Jahren

Achso, ich dachte dass du eine Beziehung zwischen den Tabellen hast.
Also dann funktioniert dein Beispiel das du am Anfang hast schon. Wenn du in Linq-Pad diese querie eingibst wirst du sehen dass alle Spalten hergenommen werden.
Ich habe dir ein Beispiel von mir angehängt, jedoch sind beide in Beziehung, was aber nichts daran ändert dass dein Beispiel ohne Beziehung auch funktioniert (falls die where-Bedingung überhaupt erfüllbar ist)

Mein Blog
Meine WPF-Druckbibliothek: auf Wordpress, myCSharp

O
oehrle Themenstarter:in
461 Beiträge seit 2009
vor 13 Jahren
Sorry, bekomme nur zwei Spalten

Hi, habe das probiert, das Ergebnis hatte ich gestern schon.
Ich bekomme nur zwei Spalten angezeigt, aber die Anzahl der Datenzeilen die Ausgegeben werden sollten die stimmt überein, wie wenn ich das mit SQL mache. Habe mir das LinqPad gezogen, dort die DB verbunden und das mal simuliert. Ich bekomme dort alle Spalten der beidne Tabellen.
Aber im C#-Prog funktionierts nict. Vielleicht spielt die Typisierung eine Rolle?

Zuallererst mache ich von der Entity eine globale Instanz, auch von jeder Tabelle.

Nach dem Initialisieren der Form, lade ich jede Tabelle in eine List <T>. Dann habe ich alle Daten im RAM, weil ich mit meinem Programm sehr viele Suchanfragen in den Daten durchführen werde.

Nun, die Daten liegen vor, ich gebe das so ein:


            var v = from k in _cnc.Kopf
                    join c in _cnc.C1
                        on k.Dateiname equals c.Bezeichnung
                    select new {k, c};

aber als Ausgabe im DataGridView bekomme ich nur zwei Spalten, mit dem Namen der Applikation und dem Tabellennamen.
So ein Käse ...

Ha, du wohl auch Schwarzwald ??

1.552 Beiträge seit 2010
vor 13 Jahren

Hä?

Ha, du wohl auch Schwarzwald ??

Also dein Problem ist dass du die Daten direkt an das DataGridView (DGV) bindest.
Anhand des Strings WindowsFormsApplication2.Kopf siehst du dass per Standard die Methode ToString() verwedet wird, die falls nicht überschrieben den Namespace der Klasse representiert. Du bekommst zwar nur 2 Spalten, jedoch befindet sich in der Spalte das komplette Object.

An diesem Beispiel siehts du wie ein Object, so wie du es machst, an das DGV gebunden wird.
Einfacher würde es IMO mit WPF gehen

Mein Blog
Meine WPF-Druckbibliothek: auf Wordpress, myCSharp

O
oehrle Themenstarter:in
461 Beiträge seit 2009
vor 13 Jahren
Wie mach ich das?

Hab mir das angesehen, aber der springende Punkt habe ich nicht gefunden ?? Wie krieg ich das Zueg ins dgv??

1.552 Beiträge seit 2010
vor 13 Jahren

Hast du es dir angesehen, oder ausprobiert?

Wenn du es probiert hast, was funktioniert noch nicht, bzw was funktioniert anders?

Mein Blog
Meine WPF-Druckbibliothek: auf Wordpress, myCSharp

O
oehrle Themenstarter:in
461 Beiträge seit 2009
vor 13 Jahren
Angesehen, nichts treffendes gesehen

Hi, habe mir das durchgeschaut, aber nicht das treffende gesehen. Gib mir mal einen Tipp.
In diesem Link wird ja nur ein Beispiel von einem Objekt gemacht. Ich habe zwei Tabellen.

Mein Ansatz:


 var v = from k in _cnc.Kopf
                    join c in _cnc.C1
                        on k.Dateiname equals c.Bezeichnung
                    select new {k, c};


            dgv_SqlAusgabe.DataSource = v.ToList();                      // Die Datensätze werden im DGV nicht ausgegeben,


Funktioniert aber nur so wie zuvor beschrieben, 2 Spalten weren ausgegeben

5.299 Beiträge seit 2008
vor 13 Jahren

soweit ich weiß, geht da nichts drumrum: wenn du eine Tabelle mit 40 Spalten haben willst, mußt du alle 40 in der L2EF-Query benennen.
So etwas wie "SELECT * FROM ..." hat Linq nicht drauf.

(OT: anonyme Typen kann man nicht an andere Methode weitergeben. Diese Einschränkung macht sie für eine Datenverarbeitung ziemlich nutzlos.
Linq-Queries, die Felder selektieren, oder Joins sind nicht rückspeicherbar in die DB, weil es keine Entities mehr sind)

Der frühe Apfel fängt den Wurm.

1.552 Beiträge seit 2010
vor 13 Jahren

Da ich sofort mit WPF angefangen habe weiss ich nicht ob es so auch in winForms geht, aber im Beispiel steht:

DataGridViewTextBoxColumn makeColumn = new DataGridViewTextBoxColumn();
makeColumn.DataPropertyName = "Make";
makeColumn.HeaderText = "The Car's Make";

probier mal folgendes:

DataGridViewTextBoxColumn makeColumn = new DataGridViewTextBoxColumn();
makeColumn.DataPropertyName = "k.Dateiname";
makeColumn.HeaderText = "Dateiname";

die datasource setzt du dann mit:

dgv.DataSource = deineLinqAbfrage;

Mein Blog
Meine WPF-Druckbibliothek: auf Wordpress, myCSharp

O
oehrle Themenstarter:in
461 Beiträge seit 2009
vor 13 Jahren
Funktioniert nicht

Habe das mal getestet. Geht nicht. Das ist doch irgendwie total irre, oder? Irgendwie muß es doch möglich sein, alle Tabellen von beiden tabellen in ein DGV zu bekommen.
Also, ich muß in meinem Projekt nur Abfragen machen, nichts zurückschreiben. In meinem Projekt habe ich eine Tabelle mit Werkzuegdaten, dazu sind 24 weitere tabellen mit Daten vorhanden, die über einen Fremdschlüssel zueinander passen. Dmit bei den Abfragen, die nacheinander von abfolgen können nicht zu viel Zeit verloren geht, sollen die Daten erst mal lokal abgelegt werden (RAM). Das geht mit DataSet oder Entitiy Framework. Habe dasselbe nun auch mal mit DataSet probiert, ist selbes Problem. Dort muß ich beide Typen in eine DataTable bringen (.CopyToDataTable()). Nun, irgendwie muß ich von
select new{k,g}
durchlaufen lassen (SChleife) und die Spaltentypen und Bezeichnungen in eine DataTable erzeugen lassen. Was anderes fällt mir nun nicht ein.
Sonst jemand eine Idee?

5.299 Beiträge seit 2008
vor 13 Jahren

beim Dataset ginge es so:
zunächst mal die getrennten Tabellen getrennt befüllen.
Dann im DGV für die Spalten aus verknüpften Tabellen DGVComboboxColumns einfügen und richtig verdrahten.
Aber im Ernst: angenommen, aus deiner Werkzeugtabelle willst du 5 Spalten zeigen, und dann aus jeder verknüpften nochmal sagenwa durchschnittlich je 3 Spalten - Wer soll sich ein DGV mit 77Spalten angucken?
Vlt. solltest du über einen EinzelblattView nachdenken.

Der frühe Apfel fängt den Wurm.

V
162 Beiträge seit 2010
vor 13 Jahren

...Irgendwie muß es doch möglich sein, alle Tabellen von beiden tabellen in ein DGV zu bekommen.
...

Bau dir eine View in der SQL Datenbank.
Die ganze O/R mapper EF scheinen bei vielen die View vergessen zu machen.

...
Also, ich muß in meinem Projekt nur Abfragen machen, nichts zurückschreiben. In meinem Projekt habe ich eine Tabelle mit Werkzuegdaten, dazu sind 24 weitere tabellen mit Daten vorhanden, die über einen Fremdschlüssel zueinander passen.
...

24 Tabellen heist mindestens 24 Spalten, puh wer soll das überblicken ?

...
Damit bei den Abfragen, die nacheinander von abfolgen können nicht zu viel Zeit verloren geht, sollen die Daten erst mal lokal abgelegt werden (RAM). Das geht mit DataSet oder Entitiy Framework. Habe dasselbe nun auch mal mit DataSet probiert, ist selbes Problem. Dort muß ich beide Typen in eine DataTable bringen (.CopyToDataTable()). Nun, irgendwie muß ich von select new{k,g} durchlaufen lassen (Schleife) und die Spaltentypen und Bezeichnungen in eine DataTable erzeugen lassen. Was anderes fällt mir nun nicht ein....

Was ist wenn sich daten verändern?
Ich bin mir nicht sicher aber eigentlich wird die SQLDB Schneller sein.
Die hat eine gute Cache und liefert dir schnelle Ergebnisse. Vorrausgesetzt das du alles richtig machst.

Das Leben ist schön!

O
oehrle Themenstarter:in
461 Beiträge seit 2009
vor 13 Jahren
Also geht das definitiv nicht mit JOIN

Hi, bevor ich da noch lang dran rumprobier, das geht also mit der JOIN definitiv so nicht, ist das korrekt???
Naja, finde das Linq schon ne tolle Sache, manche Dinge hab ich auch noch nicht begriffen. Aber wenn es sowas nicht kann, das stimmt mich ein wenig nachdenklich. Gibt's da Besserung ab FW 4.0 ??
Arbeite mit VS 2008 Prof, von 2010 hab ich mir erst die Expressversion gezogen, und weiß nicht wie da EF unterstützt wird.

Ich habe das Projekt davor mit ADO.Net realisiert. Bei der ersten Auswahl vom WErkzeugprogramm in der Kopf - Tabelle wird auf 16000 Werkzeugdaten zugegriffen, die nach diversen Abmessungen anhand der Datensaplten abgesucht werden können. Dann beginnt je nach Arbeitanwendung die Verzweigung in die 24 Tabellen. Somit muß ich z.B. wenn 3500 Datensätze in der Kopftabelle in das Auswahlkriterium fallen, von allen 3500 der Fremdschlüssel in eine Tabelle gespeichert werden (per SQL-Command), da die SQL-Abfragerei ja in den DataSet-Tabellen auch nicht funktioniert. Diese Geschichte ist für den Rechner sehr Zeitintensiv, diie Tabellen dann immer wieder direkt vom SQL-Server auszulesen, weil ich die eben nicht im Ram zwischenspeichern kann. Das ist eben das tolle an Linq to DataSet oder Linq to EF.
Muß ich mir was überlegen, wie ich die ganze Sache anders aufziehen könnte.

O
oehrle Themenstarter:in
461 Beiträge seit 2009
vor 13 Jahren
datensätze aus beiden Tabellen anzeigen geht

Hi, ich habe das Problem vor längerem gelöst. Ich habe einfach dieseleb Query nochmals abgesetzt, und in einer weiteren var abgelegt. Dann habe ich die beiden Queries in eine neue Datentabelle eingelesen. Die Spaltennamen habe ich mir über eine SChleife aus den beiden Abfrageergebnissen ausgelesen, und so die gemeinsame Tabellenstruktur erstellt, und dann die ganzen Datenreihen aus den Ergebnissen wieder mit einer Schleife 1:1 in die Tabelle geschrieben. Dann muß die Tabelle nur noch mit dem DataGridView verbunden werden. Ist zwar ertwas umständlich, aber eine andere Lösung hatte ich nicht gesehen und funktioniert schnell und gut.