Laden...

Forenbeiträge von Xynratron Ingesamt 1.177 Beiträge

26.01.2011 - 17:32 Uhr

huhu zusammen,

Ich hab mal ein wenig mit dem Problem rumgespielt. Leider scheint es **keine **zufriedenstellende Lösung zu geben.

a) Wenn man den StandardInput umleitet, dann wird cmd.exe sofort wieder geschlossen. Es werden mehrere Fehler "Handle ungültig" zurückgegeben (das sieht man aber erst, wenn man sich auch den ErrorOutput schnappt)

b) Wenn man zusätzlich Benutzername und Kennwort angibt, so bleibt das cmd-Fenster offen (läuft also), aber der StandardOutput wird vom VisualStudio abgefangen (ohne VS wird die cmd.exe sofort wieder geschlossen)

c) Wenn man StandardInput und StandardError umleitet, so bleicbt das cmd-Fenster offen und es kommt zu den schon erwähnten "Handle ungültig" Fehlern.

d) Wenn man StandardInput,Output und Error umleitet, so läuft die cmd.exe ganz brav (man kann ihr auch Befehle zuschieben). Aber natürlich sieht man dann nichts im cmd-Fenster (StdOutput ist ja umgeleitet)

Alles in allem ist es mir nicht gelungen, den StdInput umzuleiten, um Befehle an cmd.exe zu schicken und dann auch was im Fenster von cmd.exe zu sehen.

Der Fehler HandleUngültig scheint von einem nicht gesetzten StandardOutput zu kommen.

Es geht scheinbar nur "alles oder nix". Wurde auch schonmal beschrieben unter connect.microsoft.com - allerdings im Zusammenhang mit User-Credentials. Diese hatten bei mir allerdings keine wirklichen Auswirkungen.

Gestestet unter VisualStudio 2010 mit Windows 7.

😃

Xynratron

PS: ja, ich habs auch mit Administrator-Rechten versucht, kein Unterschied.
PPS: Also leider eine schlechte Nachricht @Foufou

26.01.2011 - 13:54 Uhr

Hat diese Aufgabe überhaupt auch die Aufgabe eine Form mit Buttons aufzumachen? Oder ist es wirklich ein "wenn da der Button gedrückt wird, muss es in einem Consolen-Fenster ausgegeben werden"?

Alternativ: Ein Fenster mit ner Listbox (oder so) und die Farben und schriftarten so anpassen dass es wie ein Consolen-Fenster aussieht. Könnte aber natürlich an der Aufgabenstellung vorbei sein.

😃

Xynratron

26.01.2011 - 13:41 Uhr

nein, der kompilierte Fortram-Code wird nicht nochmal übersetzt. Sonst würden ja auch Systemaufrufe (z.B. für Windows-Messages, Paint-Aufforderung etc.) immer decompiliert.

😃

Xynratron

26.01.2011 - 13:37 Uhr

huhu,

Wenn dann gehst Du die Sache eh verkehrtherum an.

Wenn ich einen Public-Key von A besitze, dann kann ich damit etwas verschlüsseln, was nur noch mit dem Private-Key von A entschlüsselt werden kann.

Also müssen Server und Client die public-Keys tauschen. Das läuft dann z.B. so:

Server zu Client Kommunikation:
Server verschlüsselt mit pub-Key-Client => Client entschlüsselt mit PrivKeyClient
Client zu Server Kommunikation:
Client verschlüsselt mit pub-Key-Serve r=> Server entschlüsselt mit PrivKeyServer

Allerdings ist dann immer nur die Verbindung verschlüsselt. Die Daten lokal musst du ja entschlüsseln um sie nutzen zu können, damit sind sie zu diesem Zeitpunkt auch immer abgreifbar.

😃

Xynratron

PS: die Schlüssel kann man auch zur Laufzeit erzeugen und dann tauschen. Dann brauchts keine fix hinterlegten Schlüssel.

26.01.2011 - 13:27 Uhr

huhu,

Du machst nicht ein Consolen-Fenster (Console.WriteLine()) auf, sondern du führst cmd.exe aus.

Für mich stellt sich hier erstmal die Frage: Warum bei einem Winform-Projekt eine Consolenausgabe implementieren? Wenns nur ums aussehen geht, dann funktioniert das auch einfacher.

😃

Xynratron

26.01.2011 - 13:22 Uhr

huhu,

Dlls habn keine eigene config zur Laufzeit. Die Werte müssen also in der App.config zu finden sein.

Alternativ kannst Du die benötigten Werte zur Laufzeit selbst setzen.

😃

Xynratron

26.01.2011 - 13:20 Uhr

huhu,
Laut MSDN wird Windows XP SP2 oder neuer benötigt.

Sollte also laufen. Kannst du dein SP nochmal prüfen?

😃

Xynratron

26.01.2011 - 13:12 Uhr

huhu,

Er liegt auf einem 1&1 Root Server.

Es ist also nicht das LAN sondern eine Verbindung zu einem Server im Internet. Das machts dann nochmal langsamer (geringere Bandbreite, langer Weg). Da bekommt man imho mit jeder DB ein Problem.

😃

Xynratron

26.01.2011 - 13:06 Uhr

na, da hab ich ja wiedermal was angefagen^^

Herbivore, ja, es ist von meiner Seite nicht besonders ernst gemeint. 🙂

🙂

Xynratron

25.01.2011 - 14:45 Uhr

huhu,

naja, der Vorteil liegt darin, dass der SQL-Server die Dateien verwaltet.
Das bedeutet unter anderem dass die Dateien bei einem Backup (wohlgemerkt ein Backup vom SQL-Server, nicht von den Dateien an sich) gesichert werden und wiederhergestellt werden können, änderungen an den Dateien werden vom SQL-Server überwacht und der Zugriff läuft über Transaktionen (kein versehentliches ändern während gelesen wird).

Ob es wirklich deutliche Vorteile gegenüber einem normalen varbinary gibt, wenn man diesen direkten Zugriff nicht benutzen kann, ist schwer zu sagen. Naja, man belastet seine Daten-Dateien (mdf) nicht mit den Binärdaten und hat mehr als 2GB zur Verfügung. Aber das wars dann wohl auch.

😃

Xynratron

24.01.2011 - 22:41 Uhr

ne, hier ist smalltalk^^ manchmal kann ich nicht widerstehen..

Es sei erwähnt: herbivore --> 30k Posts - der Screenshot war ja leider nicht echt, die 40.000 sind auch schon vorbei, also?

24.01.2011 - 22:39 Uhr

sry, hab gleichzeitig editiert^^ siehe oben

Ich hab - ehrlich gesagt - von Laufzeitanalyse im Sinne vom Informatikstudium keine Ahnung. Aber ich denke, dass die Beweisführung für Dictionary<T,K> = O(1) genau dieselbe ist, welche du bereits geleistet hast (Die Hashtable ist nicht unendlich gross, sondern läuft nach einer ähnlichen Aufgabenstellung)

Naja, aber warten wir mal, hier kommt garantiert ja noch ein Threoretik-Spezialist vorbei.

😃

Xynratron

24.01.2011 - 22:10 Uhr

huhu,

Willst du rechnen/beweisen oder lernen?

Ich würde die Implementation von List<T> bzw. Dictionary<T,K> versuchen. Die Aufgabensteklung ist ja nahezu dieselbe, die Implementation mit einem Vergleich zum Original könnte aber ein paar A-Ha-Effekte mitbringen.

😃

Xynratron

Edit: Beweisen Sie dass f(Bundesbank(n))= Ackermann(1/2) + Pierer(2) ist.

PS: hab grad nochmal den Titel gelesen, sry, damit kann ich nicht dienen. Sieht aber für mich aus (nie Informatik studiert oder so), als ob der Algorythmus O(n) gegen O(1) laufen soll. Also fällt jede Aufgabenstellung von O(x) bei x=f(y) mit f(y) hat nen Grenzwert darunter? Dann analysier doch mal Quicksort gegen Mergesort. Ich bin eher physiaklisch orientiert (gibt ja auch keinen Mathe Nobel-Preis^^) Es gilt ja auch, v(t+n)=v(t)+a(n) wenn man nicht gegen v=c läuft (oder nahezu so).

24.01.2011 - 21:59 Uhr

oO - Siemens meldet sich gerade, der Herr von Pierer, ich hab ihm gesagt, dass wir keine Schwarzgeldkonten haben. Ich hoffe das war ok....

24.01.2011 - 21:53 Uhr

huhu,

leider gibt es imho von der 33.333 keinen Screenshot, deswegen hier der Aufruf:

Einen Screenshot von herbivores 44.444 Post verewigen!

Schaft Ihr dass? Seid ihr dabei liebes Forum? Könnt Ihr Herbivore bei 44.443 festbinden und nur gegen Auflagen die 44.444 erlauben? Kann Herbivore auch selbst draufgucken und nicht einfach nur seinen Output von 300+ Postings/Tag weitermachen, sondern vielleicht zum Rauchen anfangen und dann rechtzeitig 5 min. Pause machen? (Etwas Hilfe wäre imho dringend notwendig lieber herbivore, ich kenn da auch ein paar nette Mädchen, oder Jungs, sag einfach Bescheid...wir sagen auch Deiner Frau nix!!1!)

Sollen wir Schmiergeld sammeln? Ich hab gehört Facebook zahlt ein Lösegeld und Twitter hätte gerne so nen Post-Count...

*Haare rauf* - ok, bleiben wir bei nem Screenshot. Wenn herbivore es wieder verpasst (zu pausieren) dann haben wir ja die 55.555 - irgendwann in 400 Tagen oder so.

😃

Xynratron

24.01.2011 - 21:37 Uhr

huhu,

ich hab - aufgrund meiner gern genommenen Foren-Pausen - den Anfang dieses Threads verpasst. (oder sollte ich Threat sagen?)

Naja, ich erinnere an AOL: man kann auf einem Webserver nicht einen User aufgrund der IP wegen zu vieler Anfragen bannen, da AOL tausende User mit NAT hinter genau eine IP bindet.

Desweiteren sind garantiert die meiten ISP IPv6-ready. Die Border-Router haben nur noch nicht die richtigen/fertigen Routing-Tabellen.

Zu guter Letzt: Die Designer von IPv6 haben bei gewissen Details geschalmpt, aber IPv6 hat eine Übersetzung für IPv4! Das bedeutet, die ISP können weiterhin IPv4 Adressen verteilen und routen, auch wenn das gesammte Backbone bereits IPv6 sein sollte. Oder anders gesagt:

IPv4-Adressen funktionieren auch in einem IPv6 Netzwerk!

Ok, die Router (die hauseigene Fritz!box oder so) müssen es können, aber es geht, bzw. ist definitiv im Standard vorgesehen.

Don't Panik!

😃

Xynratron

24.01.2011 - 21:03 Uhr

Hallo Campy,

ich denke, du missverstehst herbivore (oder ich mache es): auch mit WCF kannst du natürlich mehrere Datenbanken verwenden und so das aktuelle Schema praktisch komplett beibehalten. Du musst dich nicht sofort entschuldigen^^

Habt ihr bis jetzt die Mandantenfähigkeit nur über den Connectionstring unterschieden? Natürlich kann man das auch weiterhin machen, aber nen Connectionstring über WCF zu übertragen wäre etwas gewagt. Ich würde es anhand eines Logins (im WCF abzuhandeln) regeln und da dann den Connectionstring aus einer Konfig-Datei oder Datenbank auslesen/zusammenbauen.

Der Ansatz der unterschiedlichen Layer (den Du hast) lädt ja auch geradezu ein, noch nen Layer (WCF) dazwischen zu bauen.

😃

Xynratron

24.01.2011 - 19:41 Uhr

huhu,

wollte noch nen Senf in den Raum werfen: CLR ist nicht "Per Definition langsamer"; F# ist auch nicht C#. und

We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%. A good programmer will not be lulled into complacency by such reasoning, he will be wise to look carefully at the critical code; but only after that code has been identified

Ich würde das so sehen: wenn Deine Anwendung in Fortram geschrieben deinen Anforderungen entspricht, dann behalte Fortram. Wenn Du in c# Vorteile siehst, dann nimm c#.

Anschliessend kannst du immernoch performance-kritische Teile in Fortram implementieren und aufrufen. Aber natürlich sollte der Aufruf nicht den Vorteil auffressen, nur weil die "optimierte" Fortram-Funktion nur aus 3 Zeilen und 2 Integers besteht^^

😃

Xynratron

24.01.2011 - 13:53 Uhr

huhu,

Vieln Dank für eure Antwilnahme.
Problem gelöst.
Gruß GKA

naja, wie hast Du es denn gelöst bekommen?

24.01.2011 - 13:40 Uhr

Hier, auf die schnelle etwas zum erweitern und spielen.

oO - ok, wieder was gelernt, danke.

😃

Xynratron

24.01.2011 - 13:26 Uhr

huhu,

Meine Aussage von oben passt nicht, hat mich auch überrascht... Ich erklär mal was passiert:

Der SQL-Server benutzt für Filestream das Dateisystem von Windows (NTFS). Hierzu wird eine Freigabe erstellt, um auf die Daten aus dem Netzwerk zugreifen zu können. FileStream an sich ist nur ein Attribut für eine varbinary(max)-Spalte, um die Daten nicht in der DB, sondern im Dateisystem zu speichern. Hiervon verspricht man sich höhere Performance beim lesen/schreiben, da das Dateisystem einfach etwas schneller ist, als der Umweg über eine Datendatei und SQL-Server.

Wichtig hierbei ist nun, dass um diesen Geschwindigkeitsvorteil auch zu nutzen, man direkt auf die Datei zugreifen muss. Dies geschieht über eine Freigabe auf dem Server (Windows) auf welchem der SQL-Server läuft. Naja, und um auf eine Windows-Freigabe zuzugreifen, braucht man auch die entsprechenden Rechte von Windows.

**Deswegen funktioniert SQLFileStream nur mit einer Windows-Anmeldung! **

Allerdings geht der "alte" Zugriff per SQL und Varbinary immer noch:


command.CommandText = "select Top(1) Photo from employees";
//[..]
Stream data = reader.GetSqlBytes(0).Stream;

Ergo: wenn Windows-Anmeldung zur Verfügung steht, dann kann man das neue SqlFileStream benutzen. Wenn dies aber nicht möglich ist, so muss man weiterhin über GetSqlBytes arbeiten.

😃

Xynratron

24.01.2011 - 10:39 Uhr

huhu,

häng Dir doch mall Fiddler dazwischen, dann siehst Du direkt, was der Client bzw. Server schickt.

😃

Xynratron

24.01.2011 - 10:35 Uhr

huhu,

wenn Du schon das Schema hast, dann kannst Du Dir daraus auch c#-Klassen generieren lassen. Zur Laufzeit kannst du dann die Daten aus deinem XML einfach in ebendiese c#-Klassen einlesen.

😃

Xynratron

24.01.2011 - 10:10 Uhr

huhu,

Langsam wird Deine Anforderung ersichtlich. Du hast genau 2 Möglichkeiten:

a) Wie Wireshark per Treiber den kompletten Netzwerkverkehr mitschneiden.
b) Einen Proxy programmieren und dich zwischen den Browser und Server setzen.

Von der Umsetzung würde ich Möglichkeit b) vorschlagen, ist leichter zu realisieren (kein Treiber ala pcap notwendig und nur der HTTP-Traffic). Hierfür machst du 2 Ports auf, einen mit dem die Client redet, und einen mit dem der Server redet. Dann leitest du den gesamten Datenverkehr von einem Port immer zum anderen. Sprich, du bekommst eine Anfrage vom Client und leitest diese an den Server weiter. der Server antwortet und diese Daten schickst du dann einfach wieder an den Client.

Wenn Du das geschafft hast, dann kannst du anschliessend die Pakete, welche bei Dir intern durchgereicht werden, zusammensetzen und analysieren.

Wie gesagt, schau Dir Fiddler an, der macht genau das was du willst, du musst es nur nachbauen oder findest irgendwo schon ein Grundgerüst. Such einfach mal nach "c# http proxy"

😃

Xynratron

24.01.2011 - 09:59 Uhr

huhu,

Edit: folgende Aussage stimmt nicht, Erläuterung ein paar Posts tiefer.

Es wäre seltsam, wenn der Zugriff nur über Windows-Athentifizierung geht, da die im Filestream gespeicherten Daten vom SQL-Server verwaltet werden und ein etwaiger Windowsbenutzer keine Rolle spielt. Ich behaupte einfach, es geht mit SQL-Server Authentifizierung.

Wie Khalid schon sagte, benutz doch einfach die vorgesehenen Funktionen/Datentypen, dann musst Du Dich auch nicht um die Rechte kümmern.

😃

xynratron

21.01.2011 - 14:07 Uhr

spontan würde ich sagen: im IP-Stack.
Es wird einfach die Verbindung zwischen Server und Client abgebrochen. Bei der erneuten Verbindung wird dann erneut das SSL ausgehandelt - was wohl etwas zeit kostet. Wobei mir 15 Sek. auch recht lange vorkommen.

21.01.2011 - 13:15 Uhr

huhu,

Du hast ja immer das Problem dass gewisse Dinge vom eingesetzten Datebanksystem nicht unterstütz werden, oder komplett anders definiert sind. Zwar haben wir einen schönen SQL-Ansi Standard, aber inwieweit der immer unterstützt wird wissen wir ja.

Allein schon die Tatsache, dass man sich nicht darauf verlassen kann, dass Trigger oder Stored-Procs unterstützt werden ist sehr doof um einen "allgemeinen" Ansatz zu finden.

Ich würde die Version 1 nehmen aber versuchen, die Interfaces noch möglichst allgemein zu halten. Für jedes DBSystem muss dann eine Factory her, die im Fall von "nicht unterstützt" das auch recht deutlich macht. Ich denke, du kommst nicht drum herum gewisse Abstriche zu machen. Wenn ein DB-System keine Trigger unterstützt dann kann man zwar im Programm-Code durchaus ein Interface dafür haben, aber es wird eben nie funktionieren.

hmm, naja, schwierige Frage.

😃

Xynratron

21.01.2011 - 12:51 Uhr

huhu,

du kannst auch mit Fiddler schauen, ob der Server noch zusätzliche Informationen liefert.

😃

Xynratron

21.01.2011 - 12:48 Uhr

huhu,

was passiert, wenn du den Webservice jede Sekunde mal "pingst" - so dass die Session auf alle Fälle nicht abbricht?

Für mich sieht es so aus, dass nach 1 min. die Session abgebrochen wird und wieder ein Zertifikat ausgehandelt werden muss, was wieder die 15 sek. vom Anfang dauert.

😃

Xynratron

21.01.2011 - 12:46 Uhr

huhu,

wenn dein Programm von einem Benutzer ausgeführt wird, dann gelten als erstes die Rechte des Benutzers für diese Freigabe. Wenn es also ein Domänen-Benutzer ist und Lese/Schreib-Rechte auf diesen Ordner hat, dann sollte alles ohne Programmänderung funktionieren.

Wenn das nicht der Fall ist - also Benutzer nicht in Domäne, Rechner nicht in Domäne, keine Rechte - dann muss dem Server (mit der Freigabe) eine entsprechende Berechtigung übergeben werden.

Ich würde von den Möglichkeiten die Dir vbprogger nannte, Impersonation wählen, dann kann man dem Benutzer auch anch Benutzername Kennwort fragen.

😃

Xynratron

21.01.2011 - 11:37 Uhr

Ich hoffe, dass diese Frage die Grenzen des Programmier-Forums nicht übersteigt, da sie doch schon sehr mathematisch ist.

wie schon zuvor bemerkt, liegt dir hier eine gewöhnliche lineare Differentialgleichung vor.

z.B. das Eulersche Polygonzug-Verfahren heranziehen

Runge-Kutta-Verfahren (z.B. das klassische)

Die Lösung lässt sich auch Analytisch ermitteln.

Einfach Herrlich^^

20.01.2011 - 16:40 Uhr

huhu,

schau Dir mal an, was am Client wirklich als html ankommt. Ein Panel an sich wird als <div> gerendert, insofern kann man das ganze über css regeln. Vermutlich sind feste Größenangaben evtl. auch Positionen im resultierenden html vorhanden.

😃

Xynratron

20.01.2011 - 16:36 Uhr

huhu,

Aktuelle Sessions, Request etc. (und vieles mehr) bekommt man per Performance Counter. Einfach mal perfmon starten und nachgucken.

😃

xynratron

20.01.2011 - 15:19 Uhr

huhu,

wenn es wirklich "Browser" ist, dann empfehle ich Dir mal Fiddler. Ist ein kleiner feiner http-Proxy, der perfekt zum debuggen von HTTP/HTTPS-Verbindungen ist.

Wireshark halte ich da für etwas zu gross.

😃

Xynratron

20.01.2011 - 14:48 Uhr

huhu,

Ich hab dieselbe Entwicklungsumgebung und nicht diese Probleme.

Schau mal im Ressourcenmonitor, ob der Prozess beendet ist (auch wenn ein Prozess im Taskamanager nicht mehr vorhanden ist, so kann er immernoch da sein!) - Im Ressourcenmonitor wird so ein Gesist-Prozess dann grau dargestellt. Hatte sowas mal mit ProjectX und ner defekten Platte. Der versuchte Schreibzugriff lies den Prozess festhängen, auch nachdem er im Taskmanager abgeschossen war.

Da es bei Dir noch andere "exe-Dateien" betrifft, tippe ich allerdings auf den Virenscanner.

😃

Xynratron

20.01.2011 - 10:33 Uhr

Überigens gibt es die von Xynratron genannte TryParse Überladung gar nicht

Naja, etwas eigeninitiative darf man doch verlagen, oder? Vor allem wenn man nur mal schnell etwas Code hintippt können durchaus Fehler drin sein. Also kein Grund hier eine extra Anmerkung zu machen. Ausserdem verstehe ich Deine Anmerkung mit [Hinweis] Wie poste ich richtig? auch nicht.

😃

Xynratron

19.01.2011 - 16:05 Uhr

huhu,

Wenn ich mir z.B. den SQL-string im Code anzeigen lasse (bevor ExecuteNonQuery ausgeführt) wo eine der Variablen 'null' ist, kriege ich ein Doppelkomma z.B.
INSERT INTO(......) VALUES(3100,23,,2000,3000,24,25)
'null' wird einfach "geschluckt" egal ob ich es direckt in die Parameters eingebe, oder DBNull.Value benutze.

So, wie lautet denn dein aktueller SQL-Befehl? Wenn Du Parameter benutzt, dann stehen im SQL-String garantiert keine einzelnen Werte, sondern immernoch die Platzhalter. Also stimmt irgendwas von Deiner Aussage leider nicht.

desweiteren, nimm nicht den in der Textbox eingetragenen Wert - das ist ein String und kann natürlich falsch formatiert sein.

ich nehm mal den Code von oben und änder den:


if(tbLängeVon.Text.Length>0 )
    cmd.Parameter.AddWithValue("parametername",DBNull.Value);
else
{
    int EingabeInt;
    if (int.TryParse(tbLängeVon.Text))
        //Exception hier nur als Anmerkung, bitte eine Anständige Fehlerausgabe implementieren
        throw new ArgumentException("Eingabe von Textbox ist kein Integer.") 
    else
        cmd.Parameter.AddWithValue("parametername",EingabeInt);
}

😃

Xynratron

18.01.2011 - 15:08 Uhr

huhu,

Wie liest/schreibst du denn das XML-Dokument? Es gibt nämlich viele Wege das zu tun.

Gibts vielleicht eine entsprechende Option "IgnoreWhitespace" oder "PreserveWhitespaces" oder etwas anderes passendes?

Eventuell hilft dir das Attribut xml:space='preserve' weiter, also etwa so:

<w:t xml:space='preserve' >Hier steht </w:t>

Weiter unten hast du es ja in deinem Beispiel.

😃

Xynratron

17.01.2011 - 13:23 Uhr

huhu,

alternativ gäb es:

SELECT SERVERPROPERTY('IsIntegratedSecurityOnly')

1 = Windows, 0 = Mixed

😃

Xynratron

15.12.2010 - 13:16 Uhr

huhu,

guck doch nochmal oben meine beiden SQL-Statements an. Du kannst auch in Access mal die DB aufmachen, da muss es auch einen SQL-Editor geben. Mit dem kannst du rumprobieren. Ausserdem musst du das Feld, welches upgedated werden soll, auch angeben. "@memo" heisst dein Parameter und nicht das Feld in der Tabelle.

Schau Dir mal genau an, was du im code geschrieben hast und was andere vorschlagen. Da fehlen eigentlich immer Kleinigkeiten.

Vielleicht versuchst Du auch erstmal das ganze nur an die DB zu schiessen, ala:

OleDbCommand cmd= new OleDbCommand("Update Kunden set [memo]='Heidewitzka' where ID=1", empConnection);
cmd.ExecuteNonQuery()

Wenn das geht, dann die entsprechenden Parameter einsetzen.

😃

xynratron

15.12.2010 - 12:57 Uhr

huhu,

Wir haben unsere komplette BL in C# und dadurch in SVN gesichert und Versioniert. Leider habe ich noch keine "komfortabele" Lösung gefunden dies mit SP´s zu machen.

Naja, ein Datenbankprojekt benutzen, dann liegen die Objekte der DB als SQL-Scripte vor. Diese kann man wiederum ins SVN packen. Ist sehr komfortabel. Man bekommt auch mit, wenn eine änderung an einer Tabelle eine SP schrottet usw. Allerdings sind für mich SP's kein Business-Layer, sondern wenn dann dem DB-Layer zuzuordnen. Aber eigentlich "noch tiefer" da sie von der benutzten DB abhängig sind.

Denn jetzt hast du 2 Programmiersprachen, 2 Getrennte Systeme und 2 getrennte Fehlerquellen, denn jetzt musst du bei einfachen Systemen auch noch die SP verwalten.

Naja, für Selects geb ich dir bedingt recht. Man kann alles auf die spitze Treiben. Aber SPs haben ja nicht nur den Vorteil, dass man die Zugriffe kapselt (was für dich ein Nachteil ist, aber bei uns funktionieren "die 2 Systeme" ziemlich gut) sondern auch nochmal eine Abstraktionsschicht hat.
Man kann durchaus über eine SP gewisse Funktionen und Lösungen, welche gerne in einem BL abgehandelt werden, ersetzen/ergänzen. Z.B. kann man über Zugriffsrechte gleich einschränken, welche Daten von der DB zurückgegeben werden - unabhängig von einer Filterung in einem etwaigen Business-Layer. Wenn ich eine Master-Detail Struktur habe, dann kann ich das Delete über den FK per Cascade machen, oder ich prüfe vorher in der SP noch, ob das so korrekt ist und mach es erst dann (kann man auch in einem BL abfangen)

Das bedeutet jetzt für mich nicht, dass ich den BL in die DB auslagere, sondern dass ich mache Aktionen wieder dorthin zurückhole, wo sie meinem Meinung nach hingehören.

Darüber lässt sich imho trefflich streiten.

Aber klar bei "einfachen Systemen" ist das deutlich zu viel Arbeit.

😃

Xynratron

13.12.2010 - 22:13 Uhr

imho gib es zu dem Thema immer noch Meinungen und in den Jahren wechselnde Vorgehensweisen

huhu,

Also, es gibt doch 2 verschiedene Fehler: erwartete und unerwartete. Die erwarteten sind einfach: Dokumentieren und zur Anwendungsschicht weitergebn, bzw. in der Anwendungsschicht fangen und Aussagekräftig (für User und Support wie oben) angeben.

Die gemeinen sind ja Nummer 2 - egal wieviele Tests man schreibt, dass es nach 20 Jahren im vielgerühmten Quicksort doch nen Int-Überlauf geben kann - wer konnte das ahnen?
In dem Fall (und auch bei nicht gaz so sorgfältiger Programmierung) bevorzuge ich das fangen der Exeption global und mit einer Meldung ala

  1. Email an Programmierer (incl. Text und Stacktrace)
  2. Daten für Rückfragen.

das geht in einer einzigen Meldungs-Box ("Sorry, den Fehler haben wir echt nicht kommen sehen") mit "OK, Mail senden - Button". Und: im Normalfall kann das Programm einfach weiterlaufen ohne dass man neu starten muss.

Ich hab irgendwo ne sehr schöne Klasse genau dafür gesehen, war imho von Delphi inspiriert. Ich sag bescheid wenn ich wieder drüber stolper. (google mit Exeption Logger bringt schon einiges)

😃

Xynratron

PS: Google, ok: http://www.doogal.co.uk/exception.php ist nicht perfekt, aber ein guter Anfang.

13.12.2010 - 21:39 Uhr

huhu,

Transaktionen haben erstmal nichts mit StoredProcedures oder der DB zu tun. (Deswegen ist der Einwurf oben mit StoredProcedures wertlos, da man die Transaktionen in der SP immer noch rückgänig machen kann).

Transaktion bedeutet nur: "Ich Änder hier was ... bitte protokollieren .. Fehler, mach es rückgängig ODER Alles ok, behalten"

WO eine Transaktion benutzt wird ist egal. Auf DB Ebene wird es meist auch von der DB unterstützt: Ich kann stundenlang Änderungen an der DB machen, wenn ich die zurücknehme, dann ist wieder alles wie vorher.

Dein Transaction-Scope ist nur ne Hilfe, er erstellt für die DB-Verbindung eine Transaktion (wodurch die änderungen - stundenlang - wieder vernichtet werden können).

Dein "benutzte using" ist ein verdammt guter Tip: Bei einem Dispose (=vernichten der Verbindung) wird diese für neue DB-Anfragen frei. Bitte immer Dispose/Using für Connectione verwenden.
Ach ja, dieses "vernichten" der Connection im c# Code schiebt die Connection zurück in einen Connection-Pool. Dadurch ist sie sofort für andere Abfragen verfügbar, ohne dass erneut eine Verbindung zum SQL-Server aufgebaut werden muss. Der Verbindungsaufbau kostet einfach etwas Zeit, deswegen ist dieses Pooling (=ein gemeinsamer Pool, wer plantschen will darf das) ressourcenschonender und schneller. Zusammen mit Using erledigt daß das Framework für dich komplett selbst.

😃

Xynratron

13.12.2010 - 21:15 Uhr

huhu,

Naja, dass ist aber nun kein Hit einen geeigneten SessionStateProvider zu wählen und die Asp.Net-App damit zu konfigurieren.

Doch, es verführt. ASP.net frisst viel ohne dass der Programmierer drüber nachdenkt. Es ist schon ätzend, wenn die Master-Page durch ne unachtsame Referenz in die Session serialisiert wird. Und ich denke, da ist es nahezu egal, welchen SessionStateProvider man verwendet.

Wenn man den ASP-Sessionstate gleich auf DB umstellt, dann ist der wesentilch restrikter, was eine deutlichere Verbesserung ist und die Programmierer schnell aufhorchen lässt.

😃

Xynratron

PS: aber mittlerweile sind wir echt im falschen Forum^^

13.12.2010 - 13:57 Uhr

huhu,

welchen Fehler bekommst du denn?

in ASP.NET auf ein Logfile des IIS

Ich tippe auf fehlende Zugriffsrechte.

😃

Xynratron

13.12.2010 - 13:51 Uhr

huhu,

hast du nen SQL-Server Express installiert und läuft der Dienst auch?

😃

Xynratron

13.12.2010 - 13:42 Uhr

Nachtrag:

ASP.NET Cache ist mal eine Antowrt, ok, damit habe ich schon nicht soo gute Erfahrungen geamcht.

Kannst du hier genaueres erklären?

😃

Xynratron

13.12.2010 - 13:41 Uhr

huhu,

Hmm, ich haber hier jetzt einiges geschrieben, was allerdings mehr die Web-Seite beleutet, naja, was solls...

Es spielt eigentlich keine Rolle wieviele User "gleichzeitig" online sind, sondern wieviele "Hits" du pro Sekunde erwartest. Das bedeutet, wenn 10.000 User "online" sind, aber keiner was anklickt, dann hast Du auch keinen Traffic. Wenn jeder alle 10 Sekunden was anklickt, hast du nur noch 1.000 Hits/s (was immernoch recht viel ist). Ich denke, dass du aber weniger haben wirst.

Da es um eine Community-Seite geht, musst du überlegen, welche Daten denn überhaupt gecached werden können. Da sehr viele Benutzer nicht alle dieselben Daten ansehen, sondern vielmehr jeder seine "eigenen" Daten ansieht (z.B. sehen sich nicht alle gleichzeitig das Profil von Peter Müller an) wird eher auf eine Verteilung ala "10.000 User sehen sich 10.000 unterschiedliche Daten an" hinauslaufen. Das bringst dann natürlich Probleme bei den Frontendservern. Hier lassen sich aber gut viel benötige Daten oder solche, welche sich nur selten ändern cachen; z.B. Benutzernamen zu Datenbank-Nummern, Vorgegebene Stati (Online/Offline) usw.

Alles andere würde ich erstmal in der DB belassen. Man kann hier immer als erstes mit einem anständigen DB-Server Power in die Applikation bringen. Wenn alles ordentlich in Layer aufgeteilt ist, dann kann man auch immer später noch ohne Probleme Caching für einzelne Bereiche dazwischenschalten. Ausserdem cached ASP.Net auch schon.

Desweiteren würde ich die Applikation so anplanen, dass sie Problemlos per Stateserver (o.ä) und Loadbalancing funktioniert. Dann kann man nach vorne gut skalieren. Stateserver an Sich wird eine Webanwendung zwar verlangsamen, aber dadurch ermöglicht man ein einfach zu implementierendes Loadbalancing, was dann den Gesamteindruck verbessert.

Versucht Content, welcher sich nicht/selten ändert direkt auf andere Server zu legen (Z.B Bilder, Css-Dateien, Javascript usw.), das entlastet die Hauptserver und die Browser machen zusätzliche Connections auf (=Seite wird schneller).

Dann denke ich nicht, dass Du auf absehbare Zeit Performance-Probleme bekommst. Wenn wirklich dann Probleme auftauchen - wegen zu vieler User - dannsolte auch das Geld da sein, eine anständige Infrastruktur aufzubauen.

😃

Xynratron

13.12.2010 - 12:04 Uhr

huhu,

brauchst du unbedingt die zusätzlichen Klassen (Error, Info usw.)?

Mal als Denkanstoss:

public partial class TestCase {
    
    private MessageObject infoField;
    public MessageObject Info {
        get {
            return this.infoField;
        }
        set {
            this.infoField = value;
        }
    }
    private MessageObject[] messageField;
    [System.Xml.Serialization.XmlElementAttribute("Message")]
    public MessageObject[] Message {
        get {
            return this.messageField;
        }
        set {
            this.messageField = value;
        }
    }
}

public partial class MessageObject {
    
    private string textField;
    
    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string text {
        get {
            return this.textField;
        }
        set {
            this.textField = value;
        }
    }
}

Ich würde das auch nicht nur in Code versuchen zu erzeugen und immer wieder ausprobieren, sondern mit XSD.exe und einem XML-Schema arbeiten. Die c#-Klassen macht dann XSD und man kann gut anschauen was/wo/wie beschrieben wird.

Edit: Habs grad ausprobiert. Funktioniert wie Du es willst; wenn die zusätzlichen Klassen explizit benötigt werden, dann kann man einfach vererben.

Hier noch das Test-Schema

<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    
    <xs:complexType name="MessageObject">
        <xs:attribute name="text" type="xs:string" use="required" />
    </xs:complexType>
    
    <xs:element name="TestCase">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="Info"  type="MessageObject">        
                </xs:element>
                <xs:element name="Error" type="MessageObject">
                </xs:element>
                <xs:element maxOccurs="unbounded" name="Message"  type="MessageObject">                    
                </xs:element>
            </xs:sequence>
            <xs:attribute name="name" type="xs:string" use="required" />            
        </xs:complexType>
    </xs:element>

</xs:schema>

Und bitte schau, dass in Zukunft dein Code korrekt ist, wenn du hier im Forum Postest; dein XML von ganz oben ist z.B. praktisch absolut falsch^^

😃

xynratron