Laden...

DataGridView füllt sich mit Daten aus Beziehung (linq,SQL)

Erstellt von schuppsl vor 8 Jahren Letzter Beitrag vor 8 Jahren 1.054 Views
S
schuppsl Themenstarter:in
789 Beiträge seit 2007
vor 8 Jahren
DataGridView füllt sich mit Daten aus Beziehung (linq,SQL)

verwendetes Datenbanksystem: SQL Server 2008

Juhuu...

Also bei meiner Verwaltung habe ich mehrere Tabellen.
Jede Tabelle ist editierbar mit einem eigenen DateGridView, welche alle in einem TabControl sind.
Funktioniert ganz gut soweit.
Bei der Planung haben wir zuerst das Datenbankmodell entworfen und die Beziehungen festgelegt.

Mein Problem ist nun, dass ein Gridview eine zusätzliche Spalte aus der abhängigen Tabelle anzeigt, darin aber keine Daten, sondern das Objekt.

Die Objektklassen habe ich mittels O/R Designer erstellen lassen, d.h. die Tabellen reingezogen, die Beziehungen hat es einwandfrei mit abgebildet.

Beispiel:

Tabelle "Schrank" besteht aus:
SchrankNr (PK)
StandortNr

Tabelle "Standort" besteht aus:
StandortNr (PK)
Bezeichnung

Alles nvarchar(50).

Beziehung:
Schrank.StandortNr <<--->Standort.StandortNr

Heist also, ohne den entsprechenden Eintrag in Standort ist der Eintrag StandortNr in Schrank nicht möglich. Soll auch so sein.

Starte ich nun das Programm und rufe das Gridview für Standort auf, habe ich die Spalten StandortNr und Bezeichnung. Gut so.

Rufe ich das GridView für Schrank auf, so habe ich die Spalten:
SchrankNr
StandortNr - und
Standort.

Gebe ich Ordnungsgemäß die Standortnummer ein, so steht in der Spalte "Standort" Klasse.Standort (Klasse hier eben mein Objekt).

So.
Die Daten sind per linq ans GridView gebunden.

Ich kann mir vorstellen, dass es was mit der Beziehung zu tun hat, aber warum steht nur "Standort" hier und wie kann ich wenigstens die Standort.Bezeichnung in der Spalte anzeigen?
Und warum macht das GridView dies überhaupt?

S
schuppsl Themenstarter:in
789 Beiträge seit 2007
vor 8 Jahren

Keiner eine Idee?

1.029 Beiträge seit 2010
vor 8 Jahren

Hi,

dein Standort ist ein sogenanntes "Navigation-Property" - ich weiß nicht wie genau du das mit LINQ gebunden hast - vermute allerdings EntityFramework oder LinqToSql am Werk.

An dieser Stelle somit eine Warnung:
Standard für solche Properties ist LazyLoading - bedeutet: Für jedes Objekt, für das du den Standort abrufst - wird eine einzelne SQL-Abfrage abgeschickt - bei kleinen Daten unauffällig - bei auch nur geringfügig größeren Datenmengen ein Problem.

Um das mal ganz kurz zu machen:
Ich an deiner Stelle würde

  1. für sowas eine neue Klasse schreiben, welche die beiden einzelnen Objekte kapselt um diese
    besser anzeigen zu können
  2. In deiner Datenabrufklasse einen spezifischeren Abruf starten, der direkt alle gewünschten
    Eigenschaften anderer Klassen beim ersten SELECT mit abruft
    (wie das geht kann dir keiner sagen, da du die verwendete Technologie nicht genau genannt hast)

LG

189 Beiträge seit 2014
vor 8 Jahren

Hallo schuppsl,

  1. Wenn du dir das Objekt Standort zusammenbaust und dies in einer Spalte anzeigen lassen willst, was soll das GridView tun?
    Genau, es ruft die ToString()-Methode. Und da diese nicht weiß, was sie anzeigen soll von deiner Klasse (es sei denn du überschreibst die Methode) zeigt sie (oh jetzt fehlen mir die Begriffe - ich meine aber) die Objektstruktur an.
  2. Du kannst dir die Standortbezeichnung anzeigen lassen, indem du auf die Standort.Bezeichnung bindest.
  3. "per linq binden"? Lädst du nun die Daten aktiv in dein GridView (!= Binden) oder holt sich das GridView die Daten?
    (4. [Hinweis] Wie poste ich richtig? Punkt 7)

VG Ezio

S
schuppsl Themenstarter:in
789 Beiträge seit 2007
vor 8 Jahren

Moin,

es ist Linq to SQL am Werk, richtig.
Davor lasse ich die Klassen mit dem O/R Mapper generieren. Erstelle also ein neues Element (LinkToSQL) und ziehe hier aus der vorhandenen Datenbankverbindung die Tabellen rein, die ich nachher über den DataContext ansprechen kann.

Abfrage für einen Aufruf ist z:B.

  
var query = from s in mietCon.Standort select s;
dataGridViewStandort.DataSource = query;

Der generierte SQL Code scheint ok zu sein, daher wundere ich mich, dass die zusätzlichen Spalten erscheinen.

@Eizo: Mir fehlen halt auch die korrekten Bezeichnungen 😦
Aber die im Code oben zu sehen ist, binde ich die Variable für die Abfrage direkt an das GridView.

189 Beiträge seit 2014
vor 8 Jahren

Auch wenn es im ersten Moment müsig erscheint und dir auch nicht direkt bei deinem Problem hilft*, ist für mich "binden" was anderes.
Du übergibst aktiv die Daten deinem GridView.
Würdest du "binden", würde dein GridView die Datenquelle, also die Property einer anderen Klasse kennen. Wenn diese sich ändert, holt sich das GridView die Daten.
Insgesamt sieht mir das nach einem nicht optimalen Design aus (Mischung von Präsentation und DAL). Siehe dazu [Artikel] Drei-Schichten-Architektur
Und schau dir mal MVVM an.

EDIT *: Es bietet keine Antwort auf deine direkte Frage, würde dir aber bei deinem Problem helfen ... .

S
schuppsl Themenstarter:in
789 Beiträge seit 2007
vor 8 Jahren

Ok, ich werde es mir reinziehen.
Da die Zeit drängt, lasse ich das mit dem LINQ und setze die Befehle direkt per SQL ab, ist mir auch lieber, denn dann weiss ich was geschieht.


using (SqlConnection c = new SqlConnection(Properties.Settings.Default.MietkleidungConnectionString))
            {
                string befehl = String.Empty;

                befehl = "SELECT StandortNr, Bezeichnung FROM Standort";
                using (SqlDataAdapter adapter = new SqlDataAdapter(befehl, c))
                {
                    DataTable StandortTable = new DataTable();
                    adapter.Fill(StandortTable);
                    dataGridViewStandort.DataSource = StandortTable;
                }
            }

Sollte so ok sein? 🤔

1.029 Beiträge seit 2010
vor 8 Jahren

Hi,

nein - wirklich ok ist das nicht LinqToSql noch mit separaten Anfragen auf die Art zu vermischen.

An deiner Stelle würde ich mich für eine Art des Zugriffs entscheiden...

Wenn dich die zusätzliche Spalte stört: AutoGenerateColumns auf false setzen und die gewünschten Spalten selbst hinzufügen... (Dann wird auch nicht pro Datensatz ein zusätzliches Element gefetcht)

LG