ich versuche irgendwie verzweifelt ein SQL Statement in LINQ abzubilden.
Zur Verfügung habe ich 3 einzelne Datenbanktabellen, dessen Keys jeweils Adressen (adrnr), Anschriften (adrnr, ansnr) und Ansprechpartner (adrnr, ansnr, aspnr) sind.
Was ich aktuell habe, bringt nicht das Ergebnis was ich versuche abzubilden.
Ich suche im konkreten von hinten nach vorne
Den Standart Ansprechpartner (der jeweiligen Anschrift), der Anschrift(en), der Adresse. 1:n:n
Eine Adresse hat IMMER mind. 1 Anschrift und kann mehrere haben, aber nicht jede Anschrift hat zwingend einen Ansprechpartner (wovon eine Anschrift aber mehrere haben kann), wenn dann muss der Ansprechpartner mit dem StdKz == true abgerufen werden
Anhand folgendes Beispiels hatte ich mich schon versucht, jedoch kriege ich damit nur Adressen zurück die einen Ansprechpartner haben.
Wenn kein Ansprechpartner vorhanden ist, kriege ich auch die jeweilige Adresse nicht.
Danke für die Antworten.
Die Microsoft Hilfe beschreibt keine Where Clausel innerhalb des Joins.
Ebenso arbeite ich in einer Apple Umgebung und kann den Converter nicht nutzen.
Jedoch habe ich wie es so oft der Fall ist, nochmal drüber nachgedacht.
Der Fehler lag nie an meinem LINQ Tests, sondern an dem Model das ich nicht gegen NULL geprüft habe.
Der vollständige LINQ zu meiner Antwort ist:
from adr in adressen
join ans in anschriften on adr.AdrNr equals ans.AdrNr
from asp in ansprechpartner.Where(a => ans.AnsNr == a.AnsNr && a.StdKz == true).DefaultIfEmpty()
Du hast da extremen Spaghetti-Code, ein Horror das zu pflegen. Ist Dir bewusst, oder? :-)
Schau Dir [Artikel] Drei-Schichten-Architektur
- Man hat keinen DB Code in Views
- Man hat keine ViewModels im DB Code
Verwende für Rückgabe von DB-Selects einfach Projektionen. Macht man mit allen DB-Systemen und in allen Programmiersprachen/Runtimes so.
Sind auch meine ersten Versuche in dem Umfeld, man liest eben sehr viel unterschiedliches.
Use-Cases, Pluginmethode, Drei-Schichten-Architektur.
Ich kann das noch nicht ganz so verstehen mit deinem Ansatz, ist das so in etwa der Weg?
Müsste meine Datenzugriffsschicht den anonymen select als return liefern, die Logikschicht müsste ein Viewmodel draus machen und die Präsentationsschicht ruft das fertige Model ab, zeigt an und gibt Änderungen wieder an die Logikschicht, die wiederum aus dem ViewModel ein DB Model macht, das dann in der Datenzugriffsschicht verarbeitet wird?
Ich hab ein relativ altes Video gefunden, dass erstmal logisch klingt.
Ist das so zu empfehlen? 3 Schichten Architektur
Müsste meine Datenzugriffsschicht den anonymen select als return liefern,
Es ist nicht möglich anonyme Typen zurück zu geben.
Die Datenschicht sollte eigene Modelle haben, die zurück gegeben werden. Man spricht hier von Projektionen. IBM IT Basics: Selection and projection
Ist zwar von IBM, aber trotzdem eine korrekte Definition.
Hintergrund: man braucht nicht immer eine Entität, sondern man benötigt in 99% der Fällen ja ein gewisses Gesamt-Select einer Datenbank: die Projektion.
Neben der Entität liefert also die Datenschicht noch viele weitere Modelle, die man dann in der UI-Schicht konsumieren kann; zB in ViewModels übersetzen kann.
Zitat von Alesia
die Logikschicht müsste ein Viewmodel draus machen und die Präsentationsschicht ruft das fertige Model ab, zeigt an und gibt Änderungen wieder an die Logikschicht, die wiederum aus dem ViewModel ein DB Model macht, das dann in der Datenzugriffsschicht verarbeitet wird?
Siehe [Artikel] Drei-Schichten-Architektur
Nimms mir nich übel, aber auch wenn Dein verlinktes Video 14 Jahre alt is, werd ich das Video nun nicht vollständig anschauen können und reviewen, um zu sagen, obs was ist oder nicht. Da fehlt mir dann doch die Zeit für.
Die 3-Schicht-Architektur ist aber ein bewährtes Standard-Vorgehen, das es schon Jahrzehnte gibt und immer noch Gültigkeit hat. Es gibt aber natürlich auch neuere/modernere Ansätze, je nach Nutzen. Aber man sollte die 3-Schicht-Architektur schon kennen, weil sie die Basis vieler moderner Vorgehen ist.
Bin dir ja dankbar das du antwortest, dann musst du nicht noch ein Video anschauen
Aber die Grundstruktur entspricht dem was du verlinkt hast.
Grundsätzlich habe ich die Struktur so auch verstanden, wo es gedanklich aber noch hängt ist bei der Übergabe der Daten in den Service.
Das Datenbank ist unterteilt in 4 Tabellen, die für den Abruf einer "Anschrift" in meinem Fall benötigt werden.
Ich würde jetzt als nächstes 3 weitere Datenmodell Klassen bilden, die meine anderen benötigten Tabellen abruft.
Im Service ruft ich also meine Daten von jedem Datenmodell ab.
Mache ich dann im Service schon das ViewModel oder Injecte ich den Service in meine blazor Komponente und mach da erst ein ViewModel draus?
Der Service sollte das ViewModel nicht kennen. Das ViewModel ist Teil der UI. Das kennt also nur die UI.
Siehe Bild in [Artikel] Drei-Schichten-Architektur
- Oben UI
- Mitte Logik
- Unten Daten
Modelle dürften von Unten nach Oben bekannt sein, aber nicht von Oben nach Unten.
UI darf die Datenmodelle kennen, aber Daten kennt keine UI Modelle. Ein Service aus der unteren Schicht kann also niemals ein ViewModel nutzen.
Alles klar verstanden, soweit dachte ich es mir schon.
Hab gerade meine Test App parallel dazu mal in das neue System gebracht.
Aktuell hänge ich noch daran, dass in der programm.cs ein Fehler kommt, den ich gerade er-google.
"Some services are not able to be constructed"
using test.Service;
builder.Services.AddScoped<IAdresseService, AdresseService>();
Beim starten der App bekomme ich "Some services are not able to be constructed (NET.Service.IAdresseService) bezogen auf NET.Data.IAdressRepository
> Beim ganzen lesen auf google würde ich sagen, dass irgendwo die Referenz zur Klassenbibliothek fehlt.
> Hab was von DBContext Factory gelesen und so, aber irgendwie komm ich nicht weiter.
Gibt es bereits einen Artikel der mein Problem behandelt und ggf. lösen kann, oder habt ihr eine Idee dazu, wo ich was vergessen habe?
Ja, gibt ein Artikel - sollte man sich meist vor dem Coden durchlesen ;-) Dependency injection - .NET
Dependency Injection muss alle Services kennen, sonst kann es nicht funktionieren, wie TH69 schon eine potentielle Lösung dazu gesagt hat.
Vielen Dank,
das war auch die Lösung.
Ich hatte den Repository Service nicht registriert, auch nicht wirklich realisiert das die "App" den Service kennen muss, da die App keine Projektreferenz zu der Datenschicht hat.
Dachte das schlingt sich von Schicht zu Schicht, sodass nur die darüberliegende vom drunterliegenden Service wissen muss.
Die richtige Reihenfolge der Registrierung ist auch wichtig, das war mein nächster Fehler.
Die richtige Reihenfolge der Registrierung ist auch wichtig, das war mein nächster Fehler.
Dann stimmt was bei Dir nicht.
Die Reihenfolge der Registrierungen von Services - bei ASP.NET Core inkl Blazor findet das in ConfigureServices() statt - muss immer irrelevant sein, weil diese nicht garantiert ist (zB durch Fremdabhängigkeiten).
Die Reihenfolge der Middleware (also bei ASP.NET Core in Configure()) ist jedoch genau zu beachten. ASP.NET Core Middleware Order
Ja da hattest du recht.
Ich bin das nochmal durchgegangen und hab das alles behoben.
Läuft nun nach dem 3-Schichten-Prinzip wie du vorgeschlagen hast.
Bringt schon Vorteile mit sich, das stimmt.