Hallo zusammen,
ich bin auf der Suche nach einem besseren Fehlerhandling im MVC Web. Standart ist ja eine benutzerdefinierte 500er Seite die in der web.config konfiguriert wird.
Die meisten Fehler entstehen bei uns dur Usereingaben bei denen die Fehler nicht gehandelt werden. Leider meldet nicht jeder User den Fehler mit seinen Eingaben 😃
Welche Möglichkeiten gibt es herauszubekommen welche Daten eingegeben wurden um den Fehler zu werfen. Das ganze Web läuft in Azure mit Telemetrie, aber die Telemetriedaten zeigen mir auch nur die detailierten Fehlermeldungen, aber nicht mit welchen Daten diese entstanden sind.
Hat jemand einen Ansatz dafür ?
Schönes WE
Michael
Kleines Update:
Der Fehler tritt auf wenn das Programm als Webjob in Azure ausgeführt wird. Lasse ich es als Konsolenanwendung auf einem Nicht Azure Server laufen, läuft es durch.
@Abt: das verschleierte Limit der Requests lag bei 400
Michael
verwendetes Datenbanksystem: MS SQL
Hallo Zusammen,
Ist wahrscheinlich eine Grundsatzfrage, aber ich komme im Moment da nicht weiter. Mein Hauptprogramm ruft in einer Schleife 3 Methoden auf die jeweils eine DB Connection benötigen. Die Werte für die Schleife kommen aus einer anderen DB. Ich arbeite immer mit using.
Habe schon 2 Varianten probiert, einmal ein Using in jeder Methode und auch ein Using vor der Schleife und die Connection an die Methode mit übergeben.
Immer bekomme ich einen Fehler: > Fehlermeldung:
"The request limit for the database is XXX and has been reached" . Die Schleife hat 55.000 Durchläufe und wird NICHT parallel abgearbeitet.
Hat jemand eine Idee ? Müsste der Using nicht automatisch die Connection wieder schliessen ?
Michael
verwendetes Datenbanksystem: MS SQL 2016
Guten Abend,
aktuell stehe ich vor einem größeren Problem. Ich habe 3 XML Dateien von denen jede einzelne Datensätze in Form von Name/Value Pairs enthält und einem Beschreibungsfeld. Hier ein Beispiel von 2 Datensätzen:
<Compatibility>
<NameValueList/>
<NameValueList>
<Name>Make</Name>
<Value>VW</Value>
</NameValueList>
<NameValueList>
<Name>Model</Name>
<Value>Transporter V Bus</Value>
</NameValueList>
<NameValueList>
<Name>Platform</Name>
<Value>7HB, 7HJ, 7EB, 7EJ, 7EF, 7EG, 7HF, 7EC</Value>
</NameValueList>
<NameValueList>
<Name>Type</Name>
<Value>2.0 BiTDI</Value>
</NameValueList>
<NameValueList>
<Name>Production Period</Name>
<Value>2009/09-2015/08</Value>
</NameValueList>
<NameValueList>
<Name>Engine</Name>
<Value>1968 ccm, 132 KW, 180 PS</Value>
</NameValueList>
<CompatibilityNotes>Weitere Daten entnehmen Sie bitte unten aus der Beschreibung !</CompatibilityNotes>
</Compatibility>
<Compatibility>
<NameValueList/>
<NameValueList>
<Name>Make</Name>
<Value>VW</Value>
</NameValueList>
<NameValueList>
<Name>Model</Name>
<Value>Transporter V Bus</Value>
</NameValueList>
<NameValueList>
<Name>Platform</Name>
<Value>7HB, 7HJ, 7EB, 7EJ, 7EF, 7EG, 7HF, 7EC</Value>
</NameValueList>
<NameValueList>
<Name>Type</Name>
<Value>2.0 BiTDI 4motion</Value>
</NameValueList>
<NameValueList>
<Name>Production Period</Name>
<Value>2009/09-2015/08</Value>
</NameValueList>
<NameValueList>
<Name>Engine</Name>
<Value>1968 ccm, 132 KW, 180 PS</Value>
</NameValueList>
<CompatibilityNotes>Weitere Daten entnehmen Sie bitte unten aus der Beschreibung !</CompatibilityNotes>
</Compatibility>
Jede XML Datei kann dabei maximal 3000 Datensätze enthalten. Mein Problem ist dabei die 3 XML Dateien zusammenzuführen. Normal keine große Sache, aber das Feld "CompatibilityNotes" kann bei allen 3 Dateien unterschiedlich sein und muss dann zusammengefügt werden. Alle anderen Daten sind Vorgaben des Herstellers, nur die "CompatibilityNotes" sind vom Kunden editierbar und können demzufolge bei jeder Datei unterschiedlich sein auch wenn die Datensätze an sich gleich sind. Einen Weg über eine Temp DB sehe ich momentan noch nicht als optimal an, Eindimensionale Array habe ich schon zusammengefügt, mit und ohne Duplikate, habe aber momentan ein Denkblockade was dieses eine Feld angeht. Eventuell über Dataset.Merge() ??
Danke
Michael
Danke allen für die Anregungen, ich werde mir zuerst einmal das Diff. Backup anschauen, mit welchen Datenmengen ich es da zu tun bekomme.
Gruß
Michael
Moin gfoidl,
also momentan sind es ca. 50.000 Datensätze jede 5min die geschrieben werden, gelesen wesentlich weniger. Die Zahl der zu schreibenden Datensätze erhöht sich momentan statistisch gesehen um 10.000 pro Monat, bedeutet in 4 Wochen sind es 60.000 alle 5 min. Die Datenbankgröße aktuell 300Gb. Benötigt für die Benutzer werden die Daten der letzten 8 Wochen. Ich bin mir noch nicht sicher was ich mit den älteren Daten mache, löschen möchte ich noch nicht, eventuell brauche ich die noch für Statistiken.
Michael
verwendetes Datenbanksystem: MS SQL Server 2016
Hallo zusammen,
Ich würde gern mal Eure Meinung zum Thema DB Sicherung hören. Ich bin gerade dabei mit mit größeren Datenbanken zu beschäftigen. Anstreben möchte ich eine Größe von 500-1000Gb. Wie könnte eine Ausfallsicherung Eurer Meinung nach aussehen ? Aktuell habe ich 2 Server mit je 2x2Tb Platten die in einem Software Raid gespiegelt sind.
Meint Ihr eine Spiegelung der Platten reicht schon aus ? Sollte man noch eine täglichen Datensicherung einbauen ? Die wäre ja bei der Menge auch nicht klein/schnell. Oder gibt es Möglichkeiten nur Änderungen zu sichern ?
Sollte man auf dem 2. Server einfach die DB nochmal spiegeln/synchronisieren ?
Sorry, ich bin neu bei solchen Datenmengen und weiss momentan nicht wo ich ansetzen soll ?
Grüße
Michael Gross
Ich weiss das der aktuelle Ansatz besser ist. Aber die Anwendung 20x zu starten funktioniert halt aktuell, der neue Ansatz noch nicht.
Ich mach das aber nicht aus Speicherproblemen, aktuell benutze ich nicht einmal einen Bruchteil von den 28/32Gb, der Engpass ist eher die CPU.
Michael
wie bereits in einem vorherigen Kommentar geschrieben, läuft das ganze momentan in 20 Consolen Anwendungen, die Parallel laufen. Die machen 160.000 Api Calls mit Datenauswertung in zusammen 3 Min. Mein Ziel ist das ganze in eine Anwendung zu packen. Erste Tests zeigen momentan ein Problem mit zu vielen Connections (geöffnete Ports). Beim Server konnte ich das Problem mit der Erhöhung der MaxUserPorts in der Registry lösen, wie das bei Azure WebJobs geht weiss ich noch nicht. Eventuell doch wieder über mehrere Jobs verteilen, aber da weiss ich nicht wie man die synchronisiert.
Michael
Ich fürchte micha hat nun Code, der funktioniert - den er aber nicht verstanden hat 😉
Durchaus wahr, aber ich bin schon weiter als vor 3 Monaten, und auch jetzt wird es weitergehen.
Was allerdings in Zukunft auch zu einem Problem werden kann, wenn die Anzahl der Datensätze steigt.
Stimmt, aber auch bei 200.000 oder 2.000.000 muss ich trotzdem alle Datensätze abarbeiten.
Michael
jetzt siehts bei mir auch besser aus 😃
11:56:53.680609 - StartCall
11:56:53.755119 - StartCall
11:56:53.755618 - Task gestartet: 5
11:56:53.757618 - Task gestartet: 7
11:56:53.758119 - StartCall
11:56:53.758619 - Task gestartet: 6
11:56:53.760619 - StartCall
11:56:53.760619 - Task gestartet: 8
11:56:53.761619 - StartCall
11:56:53.762619 - StartCall
11:56:53.764620 - StartCall
11:56:53.766620 - StartCall
11:56:53.768620 - StartCall
11:56:53.771121 - StartCall
11:56:54.712240 - Task gestartet: 9
11:56:55.227806 - Task gestartet: 10
11:56:56.211931 - Task gestartet: 11
11:56:57.212558 - Task gestartet: 12
11:56:58.212186 - Task gestartet: 13
11:56:58.756756 - Task beendet: 5
11:56:58.758756 - Task beendet: 7
11:56:58.758756 - Task gestartet: 7
11:56:58.759756 - Task beendet: 6
11:56:58.760256 - StartCall
11:56:58.760256 - Task gestartet: 6
11:56:58.761756 - Task beendet: 8
11:56:58.762756 - StartCall
11:56:58.762756 - Task gestartet: 8
11:56:58.765757 - StartCall
11:56:58.770257 - StartCall
11:56:58.778259 - Task gestartet: 5
11:56:59.711878 - Task gestartet: 14
11:56:59.713377 - Task beendet: 9
11:56:59.716378 - StartCall
11:56:59.716878 - Task gestartet: 9
11:57:00.228443 - Task beendet: 10
11:57:00.232444 - StartCall
11:57:00.232944 - Task gestartet: 10
11:57:01.212568 - Task beendet: 11
11:57:01.216069 - StartCall
11:57:01.217569 - Task gestartet: 15
11:57:02.214231 - Task beendet: 12
11:57:02.221232 - StartCall
11:57:02.226233 - Task gestartet: 11
11:57:03.219359 - Task beendet: 13
11:57:03.766929 - Task beendet: 7
11:57:03.767929 - Task beendet: 6
11:57:03.770429 - Task beendet: 8
11:57:03.786431 - Task beendet: 5
11:57:04.719551 - Task beendet: 14
11:57:04.725051 - Task beendet: 9
11:57:05.240617 - Task beendet: 10
11:57:06.226197 - Task beendet: 15
11:57:07.228825 - Task beendet: 11
Danke
Michael
Mein Code sieht aktuell so aus:
public async Task<string> ArtikelAufteilen()
{
using (baygraphEntities db = new baygraphEntities())
{
var auktionen = (from a in db.bayEbayTracking
join b in db.bayEbayCountry on a.globalID equals b.id
where a.aktiv != false && a.abgelaufen == null
orderby a.id
select new { bayEbayTracking = a, bayEbayCountry = b }).ToList();
List<Task<string>> taskList = new List<Task<string>>();
for (int i = 0; i < auktionen.Count; i += 1000)
{
var block = auktionen
.Select(art => new Artikel()
{
id = art.bayEbayTracking.id,
artikelnummer = art.bayEbayTracking.artikelnummer,
keywords = art.bayEbayTracking.keywords,
GlobalID = art.bayEbayCountry.GlobalID
})
.Skip(i)
.Take(1000)
.ToList();
Console.WriteLine($"{DateTime.Now.ToString("hh:mm:ss.ffffff")} - StartCall");
var StartCallTask = StartCall(block);
taskList.Add(StartCallTask);
if (taskList.Count >= 10)
{
var completedTask = await Task.WhenAny(taskList).ConfigureAwait(false);
taskList.Remove(completedTask);
}
await Task.WhenAll(taskList).ConfigureAwait(false);
}
return "Ergebnis";
}
}
private async Task<string> StartCall(List<Artikel> block)
{
return await Task.Run(() =>
{
Console.WriteLine($"{DateTime.Now.ToString("hh:mm:ss.ffffff")} - Task gestartet: {Thread.CurrentThread.ManagedThreadId}");
Thread.Sleep(5000);
Console.WriteLine($"{DateTime.Now.ToString("hh:mm:ss.ffffff")} - Task beendet: {Thread.CurrentThread.ManagedThreadId}");
return "";
});
}
der Aufruf so:
static void Main(string[] args)
{
Start().Wait();
}
public static async Task Start()
{
Stopwatch watches = new Stopwatch();
watches.Start();
ApiFindingCall call = new ApiFindingCall();
string result = await call.ArtikelAufteilen();
watches.Stop();
}
eine Async Main Methode wurde angemeckert 😃
@Sir Rufo
ich habe deine Console Ausgaben mal in meinen Code eingebaut. Sieht leider nicht gut aus 😦
11:16:18.916720 - StartCall
11:16:18.936722 - Task gestartet: 5
11:16:23.938361 - Task beendet: 5
11:16:23.967864 - StartCall
11:16:23.968370 - Task gestartet: 6
11:16:28.970153 - Task beendet: 6
11:16:28.971153 - StartCall
11:16:28.971687 - Task gestartet: 5
11:16:33.972790 - Task beendet: 5
11:16:33.977291 - StartCall
11:16:33.977291 - Task gestartet: 6
11:16:38.978068 - Task beendet: 6
11:16:38.979069 - StartCall
11:16:38.979569 - Task gestartet: 5
11:16:43.980198 - Task beendet: 5
11:16:43.981698 - StartCall
11:16:43.981698 - Task gestartet: 6
11:16:48.984788 - Task beendet: 6
11:16:48.986789 - StartCall
11:16:48.987789 - Task gestartet: 5
11:16:53.989441 - Task beendet: 5
11:16:53.991433 - StartCall
11:16:53.991934 - Task gestartet: 6
11:16:58.993569 - Task beendet: 6
11:16:58.996070 - StartCall
11:16:58.996070 - Task gestartet: 5
11:17:03.997748 - Task beendet: 5
11:17:03.999777 - StartCall
11:17:03.999777 - Task gestartet: 6
11:17:09.000116 - Task beendet: 6
11:17:09.003118 - StartCall
11:17:09.008618 - Task gestartet: 5
11:17:14.009757 - Task beendet: 5
11:17:14.012256 - StartCall
11:17:14.012256 - Task gestartet: 6
11:17:19.013424 - Task beendet: 6
11:17:19.016421 - StartCall
11:17:19.016894 - Task gestartet: 5
11:17:24.018031 - Task beendet: 5
11:17:24.024532 - StartCall
11:17:24.025075 - Task gestartet: 6
11:17:29.025943 - Task beendet: 6
11:17:29.028943 - StartCall
11:17:29.029443 - Task gestartet: 5
11:17:34.030082 - Task beendet: 5
11:17:34.033081 - StartCall
11:17:34.037581 - Task gestartet: 6
11:17:39.038538 - Task beendet: 6
11:17:39.042940 - StartCall
11:17:39.043438 - Task gestartet: 5
11:17:44.044604 - Task beendet: 5
11:17:44.049106 - StartCall
11:17:44.049599 - Task gestartet: 6
11:17:49.051731 - Task beendet: 6
@Abt
natürlich ist korrekt immer die optimale Lösung. Allerdings bin ich Alleinkämpfer und brauche natürlich auch zeitnah eine Lösung.
Grundproblem ist, dass der Programmteil "StartCall()" sich aktuell in einer Konsolenanwendung befindet die ich 20x ausführe und die Skip & Take Optionen per Kommandozeile übergebe. Dies funktioniert, allerdings nicht unabhängig von mir. Letzten Sonntag gab es ein MS Update auf dem Server und das Programm lief nicht bis ich es Montag Morgen bemerkt habe. Das ist nicht optimal. Ich möchte gern die 20 Aufrufe in einer Anwendung bündeln (oder mehr, je nachdem wie die DB wächst) und die ganze Anwendung als WebJob in Azure laufen lassen.
Hatte ich mir leichter vorgestellt 😃
Michael
Ein Stück bin ich momentan weiter, so sieht es momentan aus:
public async Task<string> ArtikelAufteilen()
{
using (baygraphEntities db = new baygraphEntities())
{
var auktionen = (from a in db.bayEbayTracking
join b in db.bayEbayCountry on a.globalID equals b.id
where a.aktiv != false && a.abgelaufen == null
orderby a.id
select new { bayEbayTracking = a, bayEbayCountry = b }).ToList();
List<Task<string>> taskList = new List<Task<string>>();
for (int i = 0; i < auktionen.Count; i += 1000)
{
var block = auktionen
.Select(art => new Artikel()
{
id = art.bayEbayTracking.id,
artikelnummer = art.bayEbayTracking.artikelnummer,
keywords = art.bayEbayTracking.keywords,
GlobalID = art.bayEbayCountry.GlobalID
})
.Skip(i)
.Take(1000)
.ToList();
var StartCallTask = StartCall(block);
taskList.Add(StartCallTask);
if (taskList.Count >= 10)
{
var completedTask = await Task.WhenAny(taskList).ConfigureAwait(false);
taskList.Remove(completedTask);
}
await Task.WhenAll(taskList).ConfigureAwait(false);
}
return "Ergebnis";
}
}
private async Task<string> StartCall(List<Artikel> block)
{
return await Task.Run(() =>
{
Console.WriteLine($"Task gestartet: {Thread.CurrentThread.ManagedThreadId}");
Thread.Sleep(500);
return "";
});
}
Die Methode "StartCall" wird zwar mit unterschiedlichen Task gestartet, die aber nacheinander ausgeführt werden. Ich komm einfach nicht dahinter wo hier der Fehler liegt ?
Michael
ich denke jetzt sind wir etwas abgewichen, Frage ist immer noch wie man einen anonymen Typ in eine Klasse bringt.
Michael
@Abt
also du meinst statt die Datenbank zu öffnen, 20.000 Datensätze in 500er Blöcke aufzuteilen und die in 40 Tasks weiterzuverarbeiten wäre es besser die Datenbank zu öffnen, die Connection an die 40 Tasks weiterzugeben und in jedem Task 500 Datensätze abzufragen ?
Michael
ich würde gern je 500 Datensätze einer DB Abfrage in einem Task verarbeiten. Dazu wollte ich die Schleife durchlaufen und eine Liste mit den 500 Datensätzen an den Thread geben.
Michael
Danke für den Namenshinweis.
Naja, unelegant wäre die Klasse per Schleifendurchlauf durch die block Variable zu "füllen". Elegant wäre sowas wie
Artikelliste artikelliste = new Artikelliste()
artikelliste = block;
Michael
ich habe jetzt das gemacht:
class ArtikelListe
{
public List<Artikel> Artikel { get; set; }
}
public class Artikel
{
public string artikelnummer { get; set; }
public string keywords { get; set; }
public string GlobalID { get; set; }
}
gibt es denn einen eleganten Weg die Variable block in die Klasse Artikelliste zu bringen ?
Michael
verwendetes Datenbanksystem: MS SQL 2016
Hallo zusammen,
ich steh ein bischen auf dem Schlauch. Wie kann ich das Ergebnis der folgenden Abfrage an eine Methode übergeben.
var auktionen = (from a in db.bayEbayTracking
join b in db.bayEbayCountry on a.globalID equals b.id
where a.aktiv != false && a.abgelaufen == null
orderby a.id
select new { bayEbayTracking = a, bayEbayCountry = b }).ToList();
List<Task<IList<string[,]>>> taskList = new List<Task<IList<string[,]>>>();
for (int i = 0; i < auktionen.Count; i += 500)
{
var block = auktionen
.Select(art => new { art.bayEbayTracking.artikelnummer, art.bayEbayTracking.keywords, art.bayEbayCountry.GlobalID })
.Skip(i)
.Take(500)
.ToList();
taskList.Add(this.StartCall(block));
}
in block steht drin:
[0]{ artikelnummer = "1111111111", keywords = "iPhone", GlobalID = "EBAY-DE" }
[1] .....
Wie muss ich die Parameter in der aufgerufenen Methode definieren ? Mit StartCall(List<string[,,]> block) kommt ein Fehler.
Alternativ könnte ich natürlich eine neue Liste definieren und per Schleife aus der DB Abfrage füllen, aber ist das nicht ein Umweg ?
Danke
Michael
Hallo Gemeinschaft,
ich übergebe vom Controller zur View einen Text in einem Objekt um dann eine Wordwolke per JS darzustellen. im Objekt werden die Worte richtig mit dt. Umlauten übertragen. Aber sobald ich vom Objekt in die JS Variable übertrage per
var text = '@checkcolors.WordCloud';
sind die Umlaute zu Unicode umgewandelt. z.B "weiß" heisst dann "weiß". Gehostet wird in Azure, Serverstandort West Europa
Hat jemand einen Lösungsansatz ?
Michael
So, Daten werden jetzt in die Cosmos DB geschrieben, danke an Alle für die Unterstützung.
Michael
@Abt
Was ist mit Azure Table Storage ? Ist deutlich kostengünstiger als Cosmos DB ?
@Sir Rufo
Ist nur die Transportkomprimierung.
Michael
@T-Virus
Es geht um Produktdetailseiten von Shops. Ich möchte einen Optimierungsratgeber anbieten. Die Produktseiten bekomme ich als JSON. Die möchte ich speichern und nach gewisser Zeit diesen JSON erneut abrufen um zu schauen ob und wenn ja wie der Kunde meine Optimierungsempfehlungen umgesetzt hat. Also im Endeffekt geht es darum 2 JSON Strings (Kategoriedaten, Artikelmerkmale etc.) zu vergleichen und eine Auswertung zu machen was geändert wurde.
Michael
verwendetes Datenbanksystem: MS SQL 2016
Hallo zusammen,
aktuell habe ich ein Projekt bei dem ich gerne JSON Daten aus einer API Abfrage sammeln möchte und nach mehreren Wochen schauen möchte ob sich etwas geändert hat. Nun stellt sich die Frage in welcher Form das Speichern am besten passieren kann. Meine aktuelle Idee ist in einer SQL Datenbank in einem Textfeld den kompletten String zu speichern. Da ich noch nicht weiss wie ich die Daten später brauche halte ich es nicht für sinnvoll diese jetzt schon auf mehrere Tabellen aufzuteilen, sondern erst die Auswertung zu machen wenn die Daten wieder gebraucht werden.
Nun kommen die Daten als GZIP an, da stellt sich mir die Frage ob es nicht besser ist die gleich gepackt in der DB zu speichern und wie das funktionieren würde ?
Als letzte Alternative noch NOSQL, da fehlen mir aber die Erfahrungswerte.
Was meint Ihr dazu ?
Michael
Das Custom war die entscheidende Änderung. Schade aber auch dass Google da gar kein Ergebnis bringt. EF ist ja nun nichts seltenes.
Danke
Michael
Ok, bei Wert steht jetzt drin:
metadata=res:///.csdl|res:///.ssdl|res:///.msl;provider=System.Data.SqlClient;provider connection string="data source=.database.windows.net;initial catalog=;persist security info=True;user id=;password=**;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient"
Fehler bleibt der gleiche
Wenn ich nur das nehme was in connectionstring drinsteht:
metadata=res:///.csdl|res:///.ssdl|res:///.msl;provider=System.Data.SqlClient;provider connection string="data source=.database.windows.net;initial catalog=;persist security info=True;user id=;password=**;MultipleActiveResultSets=True;App=EntityFramework"
Fehler bleibt der gleiche
Vielleicht hilft die Info wie es in Kudu drinsteht:
SQLAZURECONNSTR_Entities = metadata=res:///.csdl|res:///.ssdl|res:///.msl;provider=System.Data.SqlClient;provider connection string="data source=.database.windows.net;initial catalog=;persist security info=True;user id=;password=*;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient"
Michael
Also exakt drinstehen habe ich unter
Name: Entities
Wert: metadata=res:///.csdl|res:///.ssdl|res:///.msl;provider=System.Data.EntityClient;provider connection string="data source=.database.windows.net;initial catalog=;persist security info=True;user id=;password=*;MultipleActiveResultSets=True;App=EntityFramework
Bei Provider stand vorher System.Data.SqlClient, das hab ich nach deinem Post geändert. Ändert aber nichts an der Fehlermeldung.
Michael
Danke,
eventuell hast du noch einen Tipp was hier falsch läuft ? Ich bekomme die Fehlermeldung:
System.ArgumentException: Keyword not supported: 'metadata'.
Michael
Danke.
Mein Connection String in der Web.config sieht folgendemaßen aus (sensible Daten hab ich durch * ersetzt):
<add name="***" connectionString="metadata=res://*/Models.***.csdl|res://*/Models.***.ssdl|res://*/Models.***.msl;provider=System.Data.SqlClient;provider connection string="data source=***.database.windows.net;initial catalog=***;persist security info=True;user id=***;password=***;multipleactiveresultsets=True;application name=EntityFramework"" providerName="System.Data.EntityClient" />
Was muss ich denn in Azure jetzt als "Name" und "Wert" eintragen ?
Danke
Michael
verwendetes Datenbanksystem: <MS SQL Server 2016>
Hallo zusammen,
ich habe folgendes Problem:
Ich habe 2 identische Web Application in Azure gehostet. Der einzige "Unterschied" ist, dass beide Application auf unterschiedliche SQL Server zugreifen. Wie kann man das am besten lösen dass ich lokal nicht mit 2 Kopien arbeiten muss ?
Ich denke die beste Lösung ist den unterschiedlichen Connection String in Azure in die Anwendungseinstellungen/Verbindungszeichenfolgen/SQL-Server einzutragen. Habe dazu nur eine Anleitung gefunden: https://azure.microsoft.com/de-de/blog/windows-azure-web-sites-how-application-strings-and-connection-strings-work/
Habe ich das richtig verstanden dass dann der Connection String in der web.config überschrieben wird ? Wie muss dass denn dann in der web.config aussehen ?
Danke
Michael
verwendetes Datenbanksystem: XML
Hallo,
ich habe vor eine ziemlich große XML Datei zu deserialisieren. Die Klasse habe ich erstellt, funktioniert auch sehr gut, nur bei der Ausgabe (Razor View) des Objects gibt es Ausnahmefehler weil nicht alle Felder des Objects befüllt sind. Gibt es eine elegante Variante, dass ich mir das einzelne Abprüfen auf null bei jedem Feld sparen kann ? Vielleicht bei der Deserialisierung dem entsprechenden Feld einen leeren Wert zuweisen wenn in der XML Datei kein Wert vorhanden ist ?
Danke für die Hilfe
Michael
verwendetes Datenbanksystem: MS SQL 2016
Ich habe eine Abfrage bei der ich mir das Ergebnis nicht erklären kann.
Ich brauche Daten aus einer Datenbank, einmal komplett und einmal gruppiert.
Folgende 2 Abfragen wollte ich dafür verwenden:
var ergebnis = (from a in tabelle1
join b in tabelle2 on a.globalID equals b.id
where a.aktiv == null
orderby a.id
select new
{
id = a.id,
keywords = a.keywords,
artikelnummer = a.artikelnummer,
globalID = b.GlobalID
}).ToList();
var groupedList = (from a in ergebnis
group a by new { keywords = a.keywords, globalID = a.globalID } into g
orderby g.Key.keywords
select new { keywords = g.Key.keywords, globalID = g.Key.globalID })
.Skip(0)
.Take(5000)
.ToList();
Problem ist dass die gruppierte Liste 200 Ergebnisse mehr bringt als die gruppierte Abfrage in der DB selbst, bei 6000 (die Menge stimmt) Ergebnissen ohne Gruppierung. Hier die gruppierte Abfrage aus der DB:
var db_group = (from b in tabelle1
join c in tabelle2 on b.globalID equals c.id
where b.aktiv == null
group b by new { keywords = b.keywords, globalID = c.GlobalID } into g
orderby g.Key.keywords
select new { keywords = g.Key.keywords, globalID = g.Key.globalID })
.Skip(0)
.Take(5000)
.ToList();
Hat jemand eine Erklärung ?
Michael
die Methode macht in 2min 60.000 Durchläufe, davon gehen ca. 1-3 nicht durch, mit einem Verbindungsabbruch. Immer mit unterschiedlichen Anforderungen. Deswegen schliesse ich mal einen Anforderungsfehler aus. So groß sehe ich das Risiko die fehlerhaften Anforderungen zu wiederholen nicht.
Michael
Hallo zusammen,
was ist die beste Möglichkeit eine Methode nach einem Fehler nochmals zu durchlaufen um doch noch ein Ergebnis zu bekommen ?
private async Task<string[,]> DownloadAndDeserializeAsync(parameter)
{
try
{
using (HttpClient httpClient = new HttpClient())
{
url = url + (page + 1).ToString();
var response = await httpClient.GetAsync(url);
if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
Verarbeitung Ergebnis
}
}
}
catch (Exeption)
{
throw;
}
}
Michael
MrSparkle,
auch an Dich ein großes Dankeschön für diesen Hinweis.
Michael
danke inflames2k, das hat mir den Tag gerettet.
Michael
aber gerne doch:
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using System.Timers;
namespace ApiCall
{
public class Program
{
private static System.Timers.Timer aTimer;
DBConfig db_config = new DBConfig();
static void Main(string[] args)
{
try
{
DBConfig db_config = new DBConfig();
if (args.Length == 2)
{
db_config.dbcount = Convert.ToInt16(args[0]);
db_config.dbskip = Convert.ToInt16(args[1]);
}
SetTimer();
Start().Wait();
Console.WriteLine("\nPress the Enter key to exit the application...\n");
Console.WriteLine("The application started at {0:HH:mm:ss.fff}", DateTime.Now);
Console.ReadLine();
aTimer.Stop();
aTimer.Dispose();
Console.WriteLine("Terminating the application...");
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
Console.ReadKey();
}
if (Debugger.IsAttached)
Console.ReadKey();
}
public static async Task Start()
{
Stopwatch watches = new Stopwatch();
watches.Start();
ApiFindingCall call = new ApiFindingCall();
var arrGesamt = await call.StartCall();
watches.Stop();
Console.WriteLine(DateTime.UtcNow.ToString() + " Auktionen eingetragen. Dauer: " + watches.Elapsed.ToString());
}
private static void SetTimer()
{
aTimer = new System.Timers.Timer(1000 * 300);
aTimer.Elapsed += OnTimedEvent;
aTimer.AutoReset = true;
aTimer.Enabled = true;
}
private static void OnTimedEvent(Object source, ElapsedEventArgs e)
{
Task t = Start();
t.ContinueWith((str) =>
{
//Console.WriteLine(str.Status.ToString());
//Console.WriteLine("Main end");
});
t.Wait();
}
}
}
hier brauch ich dann die Werte:
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
namespace ApiCall
{
class ApiFindingCall
{
public async Task<string[,]> StartCall()
{
int dbskip = db_config.dbskip;
int dbcount = db_config.dbcount;
}
}
}
an der Fehlermeldung > Fehlermeldung:
der Name db_config ist im aktuellen Kontext nicht vorhanden
Michael
Ich steh momentan ganz auf dem Schlauch. Ich brauche die Befehlszeilenargumente in einer anderen Klasse. Dazu habe ich mir eine Klasse erstellt:
public class DBConfig
{
public int dbskip { get; set; }
public int dbcount { get; set; }
}
in der Main Methode habe ich dann folgenden Teil:
DBConfig db_config = new DBConfig();
if (args.Length == 2)
{
db_config.dbcount = Convert.ToInt16(args[0]);
db_config.dbskip = Convert.ToInt16(args[1]);
}
Nur kann ich von meiner Klasse aus nicht auf db_config.dbcount zugreifen. Wenn ich DBConfig db_config = new DBConfig(); oberhalb von main in die class Program schreibe kann ich von der Main nicht darauf zugreifen.
Wo ist der richtige Ansatz ?
Danke
Michael
Hallo Abt,
vielen Dank. Ich denke aber dass ich die Klassen nicht neu definieren muss weil Sie schon vorgegeben sind im Highcharts.Net Paket. Ich habe das Beispiel nun meinem Code angepasst:
List<LineSeriesData> artikel1 = new List<LineSeriesData>();
List<LineSeriesData> artikel2 = new List<LineSeriesData>();
List<Series> keywords = new List<Series>();
foreach (var item in query1)
{
artikel1.Add(new LineSeriesData { X = DateToUTC(item.zeit), Y = item.position });
}
foreach (var item in query2)
{
artikel2.Add(new LineSeriesData { X = DateToUTC(item.zeit), Y = item.position });
}
keywords.Add(new LineSeries { Name = "Knopfzelle Uhrenbatterie", Id = "Artikel1", Data = artikel1 });
keywords.Add(new LineSeries { Name = "Knopfzelle Uhrenbatterie", Id = "Artikel2", Data = artikel2 });
ViewData["Series"] = keywords;
Das funktioniert nun schon soweit dass ich in der View nichts mehr anfassen muss wenn ich die Menge der Linien ändern möchte. Leider ist die DB Abfrage noch nicht dynamisch von der Menge her. Wahrscheinlich ich dann eine Liste welche die Listen artikel1, artikel2 usw enthält ? Aber wie bekomme ich die ? Im Buch habe ich leider nichts dazu gefunden.
Michael
Hallo,
ich benutze Highchart um meine Daten in einer Grafik darzustellen. Der Teil in der View:
@(Html.Highsoft().Highcharts(
new Highcharts
{
…
Chart = new Chart
{
Width = 1087,
Height = 400,
Type = ChartType.Area
},
…
Series = new List<Series>
{
new AreaSeries
{
Name = "USA",
Data = @ViewData[" usaData & quot;] as List<AreaSeriesData>
},
new AreaSeries
{
Name = "USSR/Russia",
Data = @ViewData[" russiaData & quot;] as List<AreaSeriesData>
}
}
}
, "chart")
und der Teil im Controller:
public ActionResult AreaBasic()
{
List<double?> usaValues = new List<double?> {
null, null, null, null, null, 6, 11, 32, 110, 235, 369, 640,
1005, 1436, 2063, 3057, 4618, 6444, 9822, 15468, 20434, 24126,
27387, 29459, 31056, 31982, 32040, 31233, 29224, 27342, 26662,
26956, 27912, 28999, 28965, 27826, 25579, 25722, 24826, 24605,
24304, 23464, 23708, 24099, 24357, 24237, 24401, 24344, 23586,
22380, 21004, 17287, 14747, 13076, 12555, 12144, 11009, 10950,
10871, 10824, 10577, 10527, 10475, 10421, 10358, 10295, 10104 };
List<double?> russiaValues = new List<double?> {
null, null, null, null, null, null, null, null, null, null,
5, 25, 50, 120, 150, 200, 426, 660, 869, 1060, 1605, 2471, 3322,
4238, 5221, 6129, 7089, 8339, 9399, 10538, 11643, 13092, 14478,
15915, 17385, 19055, 21205, 23044, 25393, 27935, 30062, 32049,
33952, 35804, 37431, 39197, 45000, 43000, 41000, 39000, 37000,
35000, 33000, 31000, 29000, 27000, 25000, 24000, 23000, 22000,
21000, 20000, 19000, 18000, 18000, 17000, 16000 };
List<AreaSeriesData> usaData = new List<AreaSeriesData>();
List<AreaSeriesData> russiaData = new List<AreaSeriesData>();
usaValues.ForEach(p => usaData.Add(new AreaSeriesData { Y = p }));
russiaValues.ForEach(p => russiaData.Add(new AreaSeriesData { Y = p }));
ViewData["usaData"] = usaData;
ViewData["russiaData"] = russiaData;
return View();
}
Leider bekomme ich es nicht hin eine Variable Menge an Graphen zu übergeben. Eine For Schleife im View bringt Fehler mit den Klammern. Gibt es keinen Weg die Liste mit den Daten dynamisch im Controller zu füllen und dann an die View zu übergeben ? Ich würde gern auch mal 1 oder 3 Listen darstellen ohne dies vorher statisch angeben zu müssen.
Danke
Michael
Hallo Gü,
ich mache das seitenweise weil ich von der API die ersten 1000 Ergebnisse haben möchte aber nur 100 auf einmal bekomme. Ich muss also abfragen url?Page=1 .... url?Page=2 usw.
Momentan verzweifle ich an JSON .... Die Deserialisierung hängt sich immer auf als ob der String nicht komplett ist.
string content = await httpClient.GetStringAsync(url + (page + 1)).ConfigureAwait(false);
Rootobject listingitem = Task.Run(() => JsonConvert.DeserializeObject<Rootobject>(content)).Result;
Michael
Guten Tag,
wenn ich verhindern möchte dass sich jemand mehrmals gleichzeitig mit den selben Benutzerdaten anmeldet, gibt es da von MS eine Lösung (ich benutze Forms Athentifizierung). oder muss ich selbst was machen ?
Wenn ja, wie wäre dazu der Ansatz ? Jeweils den angemeldeten Benutzer in die DB schreiben und bei einer Neuanmeldung prüfen ob der Benutzer schon angemeldet ist ?
Michael
ASP.NET ist für so einen Workflow die falsche Basis.){gray}
Ja aktuell als Win Programm. Wenn es fertig ist und ich mich in .NET Core eingearbeitet habe wollte ich nochmal umstellen. Mit ASP.NET mach ich die Auswertung im Frontend.
Michael
Ja, sorry ... habe ich nochmal geändert.
Michael
Guten Tag,
vielen Dank an alle die mir bis jetzt geholfen haben, hier nun eine ausführliche Schilderung der Problemstellung:
Ziel ist es mit Hilfe einer API Abfrage Positionen in Suchergebnisseiten zu speichern um Sie später auszuwerten.
Stufe 1 ist eine DB Tabelle mit 1. "dem Namen meiner Seite" und 2. "den Keywords"
Stufe 2 ist ein Api Call der maximal 10.000 Ergebnisse liefert aber paginiert zurückgegeben wird. Ich würde gern die ersten 1000 Ergebnisse abfragen (würde die Menge aber gern variabel gestalten). Maximale Ergebnisse pro Page sind 100. Der Call liefert die Anzahl der Ergebnisse und die Anzahl der Pages bei jedem Call mit. Bei 1000 Ergebnissen mache ich also 10 Aufrufe a 100 Ergebnisse mit dem Aufruf apicall.de?Page=x ... Zusätzlich gibt es noch die Beschränkung von max. 18 parallelen Aufrufen des Calls apicall.de?Page=x
Die Auswertung mache ich so dass ich die 100 Ergebnisse die ich in einer Liste zurückbekomme in einer mehrdimensionalen Liste speichere. Ich habe dann eine Liste mit 10*100 Ergebnissen die zu einer URL gehören in einer Liste. Diese speicher ich dann mit Positionsnummern in einer neuen eindimensionalen Liste, die ich danach durchlaufe und mit meinem "Namen meiner Seite" vergleiche. So bekomme ich die Position meiner Seite.
Alles ab Stufe 2 funktioniert Dank der Hilfe aus dem Forum hier.
Nur die Stufe 1, daran beiss ich mir momentan die Zähne aus. Synchron ist kein Problem, ich rufe die Datenbank ab und mache jeden Eintrag schön nacheinander. Nur Parallel will mir nicht gelingen.
Eventuell käme noch eine Stufe 0 hinzu, wenn ich bei verschiedenen Abfragen mit verschiedenen Abfrageintervallen arbeiten möchte .... Oder man müsste eine Lösung finden wenn die ganze Prozedur länger dauert als der Abfrageintervall.
Michael
Hallo gfoidl,
Vielen Dank dass du dir die Mühe gemacht hast dein Beispiel zu erläutern. Auch hast du Recht damit dass das Thema Multitasking noch sehr schwer für mich ist. Und natürlich muss man sich auch einlesen. Aber das ist bei manchen Themen nicht so einfach. Ich kann zu Google nicht sagen "Lass alles weg was nicht mehr aktuell ist" und wenn ich mir meine 1500 Seiten Bücher nehme dann gibt es da 28 Seiten über TPL mit Beispielen naja ...
Ich muss allerdings zu meiner Verteidigung sagen, dass meine Codezeilen nicht dazu gedacht waren dein Beispiel zu verändern, sondern mir fehlt zu deinem Beispiel noch eine obere Ebene.
Das bedeutet ich habe nicht eine Liste mit URLs sondern mehrere Listen, die natürlich auch parallel abgearbeitet werden sollen.
Nochmals Vielen Dank
Michael
hallo gfoidl,
bin immer noch dran an deinem Beispiel. Darf ich das denn so verstehen, dass alle Vorgänge in einem Thread nacheinander abgearbeitet werden ?
Konkret, wenn ich in einem Thread 2 Aufrufe:
Thread[] threads = new Thread[20];
threads[x] = new Thread(() => {
firstPage = apifindingcall.GetFirstPage(firsturl).GetAwaiter().GetResult();
lastPage = apifindingcall.GetFirstPage(lasturl).GetAwaiter().GetResult();
});
threads[x].Start();
habe, dann werden die 2 Methoden immer nacheinander ausgeführt in 50 Threads die parallel laufen ? Kann ich dann in diesem Thread das Ergebnis nach den 2 Methodenaufrufen in eine DB schreiben ?
Momentan versuche ich einen (oder mehrere) Deadlocks zu finden. 100 Threads laufen gut, bei 200 kommen dann die Ausnahmen.
Was wäre denn ein Szenario wenn ich 1000 Threads brauche, die 6 min insgesamt laufen, ich aber alle 5min einen Abgleich machen möchte ? Macht man dann wieder eine Skalierung auf 100 Threads a 10 Durchläufe ?
Michael