Berate seit 10++ Jahren den Mittelstand, vor allem die Maschinenbauer - und ich kenn keinen, der nicht so schnell wie möglich vom Access-Quatsch wegkommen will.
Die Vorteile, die Access vor 20 Jahren mal hatte, sind schon mehrfach überholt.
Access ist kein Tool, das Automatisierung mag, geschweige denn, dass es sicher mit Daten umgehen kann - vor allem nicht mit vielen.
Es ist dafür schlicht weg nicht gemacht worden - umso mehr jedoch dafür missbraucht worden. Viele Entwickler verdienen richtig gut an Unternehmen, die sich trotzdem mit Access verrannt haben - und den Wechsel teuer bezahlen :-)
Du kannst Glück haben und Dein Wunsch ist in einem Tag umgesetzt, Du kannst Pech haben und Du wirst mehr Zeit rein stecken, als eine Migration Dich kosten würde.
Access ist aus Sicht der Software Entwicklung einfach eine sensible, instabile Basis.
Wenn Access Deine DB exklusiv (Share Exclusive Mode) öffnet, kannst keine Verbindung öffnen. Das wird von Access Schlicht und Einfach nicht unterstützt.
Enforcst Du das, endet das i.d.R. in einer beschädigten Access Datendatei. Aber auch wenn man Access im Multi Access Mode öffnet, gibts es keinen technischen Schutz vor beschädigten Datendateien.
Zitat
Mein Problem ist, dass beim Starten immer eine Fehlermeldung kommt, dass die Access Datenbank nicht gefunden wird bzw. nicht exklusiv geöffnet werden kann
Wenn Du also eine dieser Nachrichten bekommst, dann wird das schon stimmen.
- Kontrolliere, ob der Pfad zur Access Datendatei wirklich stimmt
- Kontrolliere, dass die Datendatei nicht von einer anderen Anwendung exklusiv geöffnet wurde bzw. generell nicht, weil Du selbst keine exklusive Verbindung aufbauen kannst, wenn jemand anderes verbunden ist
Aufgeben ist keine Option, das kann man alles lernen - jede:r hat es lernen müssen.
Aber es gibt dazu viele Tutorials, womit alle an ihr Ziel kommen können.
WPF ist so konzipiert, dass man MVVM verwendet. Verwendet man das nicht, wird man viele Probleme haben und Workarounds bauen müssen.
Das ist 10x schwerer und komplexer als MVVM zu lernen und anzuwenden - und am Ende besteht die Anwendung aus Kraut und Rüben.
Ja, das ist eine Einstiegshürde und ja, mit einem Try-And-Error-Vorgehen, das man zB. bei WinForms durchaus anwenden konnte, um schnell zu Ergebnissen zu kommen, klappt bei MVVM - egal ob nun bei WPF oder bei Angular, in der Regel nicht.
Da wird man kaum um echte Tutorials drum herum kommen, sonst kann man das Konzept eigentlich auch nicht verstehen.
Beim WPF "Nachfolger" MAUI kann man auch den MVU Pattern verwenden, das ein etwas leichtgewichtigeres Konzept verfolgt.
In WPF kann man MVU ohne entsprechende Bibliotheken (wie von Elmish) leider nicht anwenden.
Ja, Access vermeiden.
Access ist keine echte Datenbank und hat etliche Einschränkungen und Fehlerpotentiale, darunter wie auf die Datenquelle zugegriffen werden kann (=> exklusiv).
Dafür gibts sicher elegantere Lösungen, aber sofern Du einen DispatcherTimer sollte es das Pausieren hier nicht geben.
Du arbeitest sauber nach MVVM mit ViewModels und einem entsprechenden Binding? [Artikel] MVVM und DataBinding
Mit Reactive Extensions in .NET könnte man das komfortabel über eine Timer Subscription lösen.
// ViewModel
IsEnabledSubmitButton = false;
_isEnabledSubmitButtonDelaySubscription =
Observable.Timer(TimeSpan.FromSeconds(50))
.Subscribe(
x =>
{
IsEnabledSubmitButton = true;
if (_isEnabledSubmitButtonDelaySubscription is not null)
{
_isEnabledSubmitButtonDelaySubscription.Dispose();
_isEnabledSubmitButtonDelaySubscription = null;
}
});
Ohne genaue Exception und dazugehörigen StackTrace ist das für uns Glaskugelraten.
Da sowohl System.IO.Compression wie auch das von Dir genannte Paket sehr weit verbreitet ist - auch auf Enterprise-Ebene - ist die Wahrscheinlich gering, dass es an den Dependencies selbst liegt.
Erklär mal, was Du überhaupt tun willst - dann können wir Dir sagen, ob das mit dem Timer überhaupt sinnvoll ist, oder ob Du im Dunkeln tappst.
Timer in Pages sind sehr selten sinnvoll.
Wobei ich mich hier generell frage, warum hat TaskTO nicht eine Methode zum Abfragen der OpenTasks?
Glaube die Architektur-Leichen liegen noch an anderen, zentraleren Stellen (siehe Service Locator), die hier keinen Einfluss haben.
Die Methode hier kannst halt nur so weit optimieren, wie es die Umgebung zulässt.
Ich nehm an, dass var openTasks eine List<TaskTO> ist (Käse hier var zu verwenden, but nvmd). Dictionary besitzt eine sehr bequeme Methode, wie man einen Key mit Value in einem Rutsch erzeugen kann, ohne a) eine neue Liste zu erstellen und b) manuell kopieren zu müssen: TryAdd.
Den Zustand einer leeren Liste muss es hier nie geben.
Perfektes Beispiel wie wichtig es ist, die Dinge zu kennen, die man verwendet - oder mal in die Docs zu spicken. Tut nicht weh :-)
Wenn man in der Textdatei die Anwendung mit Parametern zum Start angibt, kann man das wunderbar als Backdoor verwenden, um Schadcode zu laden.
Herrlich :-)
Befass Dich mit den Themen :-)
Die Microsoft Docs sind bei solchen Basis-Themen sehr gut. Einfach mal ein Blick rein werfen.
- Dependency Injection statt Service Locator Pattern -> Dependency injection in .NET
- Auf unnötige Allocations verzichten (zB null ist nicht böse, wenn man es richtig verwendet :-) bzw. auf Allocations verzichten, wenn sie ohnehin im nächsten Schritt überschrieben werden (hier if/else)
- Asynchrone Programmierung anwenden -> Asynchronous programming in C#
Werd jetz aber nich den Code für dich refrakturieren - soll ja ein Lerneffekt für Dich sein :-)
Was ich so sehe:
- Die Art und Weise, wie der Service Locator Pattern angewendet ist, ist ein Anti Pattern
- Des weiteren allokierst Du sehr viele Ressourcen unnöttig (zB die leere Liste), die Du dann im nächsten Schritt wieder überschreibst
- Offenbar werden synchron mehrere Quellen angesprochen, was blockierender Code darstellt
Beachte, dass Du je nach Lizenz die Drittanbieter-DLL nicht mit ILMerge einbetten darfst.
In 99% der Fälle ist das untersagt. Dein Paket verwendet MS-PL als Lizenz, in der das aber _glaube ich_ erlaubt ist.
Von was? Weiß nicht, was Du meinst.
Hast ja nun viele Infos bekommen, die für eine Recherche-Basis dienen.
Für ne Google Suche bist sicher selbst alt genug :-) Ansonsten präzisere Fragen stellen.
Die bessere Lösung ist immer, dass ein Client sich mit einer HTTP-API verbindet, und diese API mit dem SQL Server kommuniziert. Ob das REST, GraphQL, gRPC oder sonst was ist, ist erst mal sekundär.
Jedenfalls muss durch diese Art a) der Client niemals mit Server Credentials umgehen und b) kann der SQL Server über das Netzwerk so gesichert werden, dass er nur von der HTTP API Anwendung erreichbar ist.
Jeder DB Hersteller sagt Dir nämlich, dass eine Datenbank über ein Netzwerk niemals exposed werden sollte, was bei einer direkten Client-Anwendung aber immer notwendig ist. Cloud-Anbieter haben deswegen bei all ihren Datenbank-Konfigurationen per default es so eingestellt, dass die Datenbank nicht aus dem Internet erreichbar ist - Du musst es bewusst aktivieren.
Des weiteren kann der Client ein völlig anderes Authentifizierungssystem verwenden (zB OpenID + OAuth) als die Verbindung von HTTP API zu SQL Server (Zertifikate, Active Directory..).
Je nachdem was Du für eine Plattform nutzt, kannst Du mit Datenbanken und Backend-Services vollständig ohne Credentials arbeiten.
Azure hat zum Beispiel das Feature von Managed Identities, quasi Passwort-lose Authentifizierung von Azure Services untereinander auf Azure. Geht aber leider nur auf Azure, nicht On Prem und die anderen Cloud-Provider bieten das in diesem Umfang (noch) nicht an (AWS hat den Identity Service, aber der is eher rudimentär).
Authentifizierung bzw. Authorisierung von Benutzern ist niemals Aufgabe der Datenbank.
IDs sind eindeutige Bezeichner für den DOM, spielt für Form Posts keine Rolle; werden auch nicht mit gesendet.
Form Names arbeiten mit dem name-Attribut, müssen bei Collections nach Name[] aufgebaut werden, gibt zwei Schreibweise.
- Name[] und die Value für einfache Listen (zB wenn man nur eine Liste von Int erwartet)
- Name[Index].Property und die Value, wenn man mit Objekten arbeitet
Bekanntes Thema, solltest bei der Google Recherche über entsprechende Themen gestolpert sein.
Beides sind aber nur Methoden, um ein Label dynamisch zu erzeugen.
Erzeug doch das Label einfach direkt mit HTML Code? Ist auch 100 mal effizienter als das ständig in einer Runtime in einer Schleife zu erzeugen.
Man braucht quasi kein einziges dieser Form-Helper in ASP.NET. Alles nur Komfort, der aber auch gerendert werden muss - wenn man das überhaupt so nennen kann. Persönlich find ich das kein Komfort, macht vieles unnötig komplex. HTML ist bei sowas 1000 mal einfacher zu handlen.
Wir hier im Forum verwenden bei sowas immer folgenden Grundaufbau:
Das Binding und die Darstellung der Daten habe ich soweit hinbekommen und auch das Speichern geänderter Daten funktioniert soweit.
Mh. Ne :-)
Was Du da gemacht hast, ist nicht, was man unter Datenbindung versteht.
In WPF macht man das mit Hilfe von MVVM und entsprechenden ViewModels. [Artikel] MVVM und DataBinding
Bei MVVM brauchst das ganze Thema Code Behinds und Click-Events nicht.
Da macht man das mit Commands, und eben diesen View Model (für die View).
Das ViewModel kennt dann wiederum zB. Logik-Modelle.
--
Nur als Info, rein technisch, weil Du von "Datenbank" sprichst:
Mit Dein XML-Load, in dieser Form, lädst führst Du Datenbank-Operationen direkt in der UI aus
-> [Artikel] Drei-Schichten-Architektur
Wenn Du Instanz B der Anwendung informieren willst, weil Instanz A (also Dein Dienst) etwas in der Datenbank aktualisiert hat, dann solltest Du das - wenn möglich - über ein entsprechenden Service und einer Notification (i.d.R. Websockets) umsetzen; nicht direkt über die Datenbank.
Dass jetzt schon zig Anwendungen direkt an der DB hängen und damit Schema-Änderungen nen riesen Impact hat: risk by design. Daher nimmt man eben Services :-)
Datenbank-seitige Notifications wie Eventalerter, SqlDependency oder SqlDependencyRequest (Query Notifications) haben unheimlich viele Nachteile (Skalierung, Permission, Usability, Performance...) und Limitations.
Eine gute Idee, jetzt noch mehr Verantwortung in die DB zu schieben...? Selten der Fall :-)
Der Anwendungsfall von Eventalerter, SqlDependency oder SqlDependencyRequest ist daher vergleichweise selten passend.
Report von Campy, dass Google das falsche Datum anzeigen bei Suchergebnissen zeigen würde.
Hintergrund ist, dass wir derzeit kein OpenGraph bzw. SchemaOrg für Themen implementiert haben.
Daher wählt Google das erste Datum auf der Seite, das gefunden wird.
Ist bekannt; wir arbeiten derzeit an der Implementierung von SchemaOrg.
PS: Originalthema gelöscht, da Bugs bitte hier gepostet werden sollen. Macht es einfacher.
Danke.
"User Accounts" gibts nicht, sondern nur "Individual Accounts".
Bei "Individual Accounts" wird ASP.NET Core Identity verwendet, das gewisse Razor Pages eingebettet hat, die Du so nicht im Projekt siehst.
Willst Du eigene, müssen diese überschrieben werden:
- Rechtsklick auf das Projekt
- New Scaffolding Item
> Dann werden paar NuGet Pakete installiert
> Dann öffnet sich ein Scaffolding Window "Add Identity"
- Dort die Pages anklicken, die Du überschreiben willst.
Oder Du verzichtest ganz auf ASP.NET Core Identity.
Das im gezeigten Link ist eine sehr sehr vereinfachte Kommunikation von 2 Forms.
Gerade wenn man aber Objekte hat, die man über mehrere Forms bekannt machen will (zB durch Auswahlen), ist ein Messaging Pattern der bessere Weg.
Und in welchem Buch steht, dass Controls schubsen ne gute Idee ist? :-)
Die Frage wäre noch offen.
Da man in WPF mit Datenbindung arbeiten sollte, und mit nichts anderem, sind die Namen der Controls (x:Name) i.d.R. irrelevant.
Auch greift man von logischem Code nicht auf die Controls zu.
Deswegen gibt es den MVVM Pattern. Verwendet man diesen nicht, wird man von Workaround über Workaround stolpern. [Artikel] MVVM und DataBinding
Über ein ViewModel und dessen Eigenschaften kannst Du dann auch dynamisch in XAML reagieren und Dinge ein/ausblenden.
Aber nicht umgekehrt.
Nur weil eine Datei in wwwroot liegt wird diese noch lange nicht geladen.
JavaScript Dateien müssen über HTML (Layout wenn Global, in der jeweiligen Page wenn Local) mit dem <script>-Tag bekannt gemacht werden.
Danach erst stehen die Funktionen im DOM zur Verfügung.
Aber Achtung: das Laden einer JS-Dateien kann manchmal ein paar Millisekunden brauchen.
Man muss also sicher sein, dass die JS-Datei zur Ausführung der Funktion auch wirklich vollständig verarbeitet wurde.
XML hat seine Vorteile, Json hat seine Vorteile - und beide Nachteile.
Die Entwicklergemeinde ist ganz klar pro Json und hat dafür gesorgt, dass das eben so ist, wie es heute ist.
Sei froh, dass es kein YAML ist - aber ich will es auch nicht prophezeien ;-)
Control-Elemente Schubsen ist nicht so nen dolles Ding :-)
Sowas löst man eigentlich über Datenbindungen bzw. mit Hilfe von State Handling / Messaging Pattern.
In .NET kann dazu einfach Rx.NET oder ReactiveUI verwenden.