N-Schichtdatenbankanwendung, ohne dass ein ORM, wie spezifiziert die Benutzeroberfläche, was es Daten Anzeige muss?

StackOverflow https://stackoverflow.com/questions/1524367

Frage

Ich suche Zeiger und Informationen hier, ich werde diese CW machen, da ich vermute, es hat keine einzige richtige Antwort. Dies ist für C #, daher werde ich einige Hinweise auf Linq unten machen. Ich entschuldige mich auch für den langen Pfosten. Lassen Sie mich die Frage hier zusammenfassen, und dann die volle Frage folgt.

Zusammenfassung: In einem UI / BLL / DAL / DB 4-Schicht Anwendung, wie können Änderungen an der Benutzeroberfläche, mehr Spalten zeigen (sagen wir in einem Gitter), zu vermeiden undicht durch die Business-Logik-Schicht und in den Datenzugriff Schicht, zu halten, um die Daten anzuzeigen zu bekommen (es ist bereits in der Datenbank vorausgesetzt).


Lassen Sie uns annehmen, eine geschichtete Anwendung mit 3 (4) Schichten:

  • User Interface (UI)
  • Business Logic Layer (BLL)
  • Data Access Layer (DAL)
  • Datenbank (DB, die vierte Schicht)

In diesem Fall wird die DAL ist verantwortlich SQL-Anweisungen für den Aufbau und sie gegen die Datenbank ausgeführt wird, zurückgegebenen Daten.

Ist der einzige Weg, um „richtig“ zu konstruieren, eine solche Schicht nur immer tun „select *“? Für mich ist eine große no-no, aber lassen Sie mich erklären, warum ich frage mich.

Lassen Sie sich sagen, dass ich will, für meinen UI, alle Mitarbeiter anzuzeigen, die einen aktiven Beschäftigungsrekord haben. Mit „aktiv“ Ich meine, dass die Beschäftigung Datensätze von-bis Daten enthalten heute (oder vielleicht sogar ein Datum kann ich in der Benutzeroberfläche festgelegt).

In diesem Fall lassen Sie uns sagen, dass ich eine E-Mail an alle diese Personen senden wollen, so dass ich einige Code in der BLL haben die sicherstellt, ich habe nicht bereits E-Mail an den gleichen Leuten bereits verschickt, etc.

Für die BLL, braucht es nur minimale Mengen an Daten. Vielleicht ruft sie die Datenzugriffsschicht bis zu dieser Liste der aktiven Mitarbeiter, und dann eine Liste der E-Mails ein Anruf, um es aus gesendet hat. Dann schließt er sich an diejenigen, und baut eine neue Liste. Vielleicht ist dies mit Hilfe der Datenzugriffsschicht getan werden könnte, das ist nicht wichtig.

Wichtig ist, dass für die Business-Schicht, gibt es wirklich nicht viele Daten er benötigt. Vielleicht braucht es nur die eindeutige Kennung für jeden Mitarbeiter, für beiden Listen, auf passen, und dann sagen: „Dies sind die eindeutigen Kennungen von denen, die aktiv sind, dass Sie nicht bereits eine E-Mail geschickt“. Muss ich DAL Code dann konstruieren, dass Konstrukte Anweisungen SQL, dass nur das, was die Business-Schicht Bedürfnisse abrufen? D. h. "SELECT id FROM Mitarbeiter WHERE ..." nur?

Was mache ich dann für die Benutzeroberfläche? Für den Anwender wäre es vielleicht am besten, viel mehr Informationen enthalten, je nach Warum Ich möchte E-Mails versenden. Zum Beispiel könnte ich einige rudimentäre Kontaktinformationen enthalten sein sollen, oder die Abteilung für die sie arbeiten, oder ihre Manager Name usw., nicht zu sagen, dass ich zumindest Name und E-Mail-Adresse Informationen zu zeigen.

Wie kommt die Benutzeroberfläche, die Daten? Muss ich die DAL ändern, um sicherzustellen, dass ich genug Daten zurück an die UI zurückkehren? Muss ich die BLL ändern, um sicherzustellen, dass es genügend Daten für die Benutzeroberfläche zurückgibt? Wenn das Objekt oder die Datenstrukturen aus dem DAL zurück zum BLL zurück kann auch auf der Benutzeroberfläche gesendet werden, vielleicht nicht die BLL nicht brauchen viel von einer Änderung, aber dann Anforderungen der UI Auswirkungen eine Schicht über das, was sie kommunizieren soll mit . Und wenn die beiden Welten auf unterschiedliche Datenstrukturen arbeiten, würden Änderungen wahrscheinlich beide zu tun.

Und was dann, wenn die UI geändert wird, um den Benutzer zu helfen, noch weiter, um mehr Spalten hinzufügen, wie tief würde / soll ich gehen, um die Benutzeroberfläche zu ändern? (Die Daten unter der Annahme ist in der Datenbank bereits so keine Änderung erforderlich ist.)

Ein Vorschlag, die kommen muss, ist Linq-To-SQL und IQueryable zu verwenden, so dass, wenn die DAL, die sich mit, was (wie in, welche Arten von Daten) und warum (wie in WO-Klauseln) zurück IQueryables, die BLL könnte möglicherweise diejenigen Rückkehr in die Benutzeroberfläche, die dann eine Linq-Abfrage konstruieren könnte, die die Daten abrufen würde es braucht. Der Code Benutzeroberfläche könnte dann in den Spalten ziehen muss. Dies würde WOrk da mit IQuerables würde die UI am Ende tatsächlich die Abfrage ausgeführt wird, und es könnte dann verwenden „wählt neue {X, Y, Z}“, um anzugeben, was er braucht, und auch in anderen Tabellen verknüpfen, falls erforderlich.

unordentlich Das sieht für mich. Dass die Benutzeroberfläche führt den SQL-Code selbst, auch wenn es hinter einem Linq Frontend versteckt wurde.

Aber damit dies geschehen kann, die BLL oder die DAL sollte die Datenbankverbindungen zu schließen, und in einer IoC Art der Welt nicht erlaubt sein, der DAL-Dienst könnte ein bisschen erhalten angeordnet früher als der UI-Code möchte , so dass Linq Abfrage könnte nur mit der Ausnahme, „kein Zugriff auf ein angeordnete Objekt“ enden.

So freue ich mich für Zeiger. Wie weit weg sind wir? Wie gehen Sie mit diesem? Ich halte die Tatsache, dass Änderungen an der Benutzeroberfläche durch die BLL austritt und in die DAL eine sehr schlechte Lösung, aber im Moment sieht es nicht wie wir es besser machen können.

Bitte sagen Sie mir, wie dumm wir sind und beweisen, mich falsch?

Und beachten Sie, dass dies ein Legacy-System ist. das Datenbankschema zu ändern, ist seit Jahren nicht mehr in den Geltungsbereich noch so eine Lösung zu verwenden ORM-Objekte, die das Äquivalent von im Wesentlichen tun würde „select *“ nicht wirklich eine Option ist. Wir haben einige große Tabellen, dass wir möchten, dass durch die gesamte Liste der Schichten nach oben ziehen vermeiden.

War es hilfreich?

Lösung

Mit dem Konzept eines View-Modell (oder Datentransferobjekte), die UI Verbrauch Fälle sind. Es wird die Aufgabe des BLL, diese Objekte zu nehmen, und wenn die Daten nicht vollständig sind, fordert zusätzliche Daten (die wir nennen Modell). Dann kann die BLL richtige Entscheidungen darüber treffen, welche Modelle zur Rückkehr anzuzeigen. Lassen Sie sich nicht Ihr Modell (Daten) Besonderheiten Permeat der Benutzeroberfläche.

UI <-- (viewmodel) ---> BLL <-- (model) --> Peristence/Data layers

Diese Entkopplung ermöglicht Anwendung besser zu skalieren. Die Persistenz Unabhängigkeit denke ich nur natürlich fällt aus diesem Ansatz, wie Konstruktion und Spezifikation der Ansicht Modelle unter Verwendung linq2ql oder eine andere ORM-Technologie flexibel in der BLL tun konnte.

Andere Tipps

Das ist überhaupt nicht ein einfaches Problem zu lösen. Ich habe viele Versuche (einschließlich der IQueryable Ansatz, den Sie beschreiben) gesehen, aber keine, die perfekt sind. Leider warten wir noch auf die perfekte Lösung. Bis dahin müssen wir mit Unvollkommenheit behelfen.

Ich bin völlig einverstanden, dass die DAL Bedenken sollten nicht zugelassen werden, zu den oberen Schichten entweichen durch, so ein isolierendes BLL notwendig ist.

Auch wenn Sie nicht den Luxus haben, die Datenzugriffstechnologie in Ihrem aktuellen Projekt neu zu definieren, hilft es immer noch über die Domain Model in Bezug auf die Persistenz Unwissenheit zu denken. Ein corrolary von Persistence Ignorance ist, dass jede Domain Objekt eine in sich geschlossene Einheit ist, die keine Ahnung von Sachen wie Datenbankspalten hat. Es ist am besten Daten integretiy als Invarianten in solchen Objekten zu erzwingen, aber das bedeutet auch, dass ein instanziiert Domain Object alle geladenen seiner konstituierenden haben Daten. Es ist ein Entweder-oder Satz, so dass der Schlüssel eine gute Domain Model, das sicherstellt finden wird, dass jede Domain Object halten (und geladen werden müssen), um eine ‚geeignete‘ Menge an Daten.

Zu granulare Objekte zu gesprächig DAL-Schnittstellen führen kann, aber zu grobkörnig Objekte zu viel irrelevante Daten werden geladen führen kann.

Eine sehr wichtige Übung ist zu analysieren und richtig die Domain des Modells Aggregates modelliert, so dass sie die richtige Balance. Das Buch Domain-Driven Design einige sehr aufschluss Analysen der Modellierung Aggregate enthält.

Eine andere Strategie, die in dieser Hinsicht hilfreich sein kann, ist, darauf abzielen, die Hollywood-Prinzip so weit wie möglich anzuwenden. Das Hauptproblem beschreiben Sie Bedenken Abfragen, aber wenn Sie Ihren Fokus verschieben können mehr Befehls orientiert sein, können Sie in der Lage sein, einige mehr grobkörnig Schnittstellen zu definieren, die nicht erfordert Sie immer Last zu viele Daten.

Ich bin mir nicht bekannt, dass einfache Lösung für diese Herausforderung. Es gibt Techniken, wie die, die ich oben beschrieben, können Ihnen helfen, einige der Probleme anzugehen, aber am Ende ist es immer noch eine Kunst, die Erfahrung, Geschick und Disziplin nimmt.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top