Laden...

Forenbeiträge von micha0827 Ingesamt 85 Beiträge

14.07.2018 - 13:14 Uhr

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

08.04.2018 - 20:17 Uhr

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

08.04.2018 - 14:05 Uhr

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

28.12.2017 - 21:46 Uhr

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

28.12.2017 - 21:02 Uhr

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

27.12.2017 - 18:53 Uhr

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

27.12.2017 - 17:24 Uhr

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

30.10.2017 - 15:19 Uhr

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

30.10.2017 - 14:53 Uhr

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

30.10.2017 - 13:07 Uhr

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

30.10.2017 - 11:58 Uhr

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

30.10.2017 - 11:43 Uhr

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 😃

30.10.2017 - 11:23 Uhr

@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

30.10.2017 - 10:44 Uhr

@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

30.10.2017 - 07:30 Uhr

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

29.10.2017 - 22:51 Uhr

ich denke jetzt sind wir etwas abgewichen, Frage ist immer noch wie man einen anonymen Typ in eine Klasse bringt.

Michael

29.10.2017 - 22:27 Uhr

@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

29.10.2017 - 22:15 Uhr

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

29.10.2017 - 21:55 Uhr

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

29.10.2017 - 21:42 Uhr

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

29.10.2017 - 21:15 Uhr

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

21.10.2017 - 16:12 Uhr

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&#223". Gehostet wird in Azure, Serverstandort West Europa

Hat jemand einen Lösungsansatz ?

Michael

21.10.2017 - 16:01 Uhr

So, Daten werden jetzt in die Cosmos DB geschrieben, danke an Alle für die Unterstützung.

Michael

14.10.2017 - 13:39 Uhr

@Abt
Was ist mit Azure Table Storage ? Ist deutlich kostengünstiger als Cosmos DB ?

@Sir Rufo
Ist nur die Transportkomprimierung.

Michael

14.10.2017 - 13:27 Uhr

@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

14.10.2017 - 12:53 Uhr

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

08.10.2017 - 22:19 Uhr

Das Custom war die entscheidende Änderung. Schade aber auch dass Google da gar kein Ergebnis bringt. EF ist ja nun nichts seltenes.

Danke
Michael

07.10.2017 - 18:34 Uhr

Ok, bei Wert steht jetzt drin:

metadata=res:///.csdl|res:///.ssdl|res:///.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=.database.windows.net;initial catalog=;persist security info=True;user id=;password=**;MultipleActiveResultSets=True;App=EntityFramework&quot;" 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=&quot;data source=.database.windows.net;initial catalog=;persist security info=True;user id=;password=**;MultipleActiveResultSets=True;App=EntityFramework&quot;

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=&quot;data source=.database.windows.net;initial catalog=;persist security info=True;user id=;password=*;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient"

Michael

07.10.2017 - 18:13 Uhr

Also exakt drinstehen habe ich unter

Name: Entities
Wert: metadata=res://
/
.csdl|res:///.ssdl|res:///.msl;provider=System.Data.EntityClient;provider connection string=&quot;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

07.10.2017 - 17:30 Uhr

Danke,

eventuell hast du noch einen Tipp was hier falsch läuft ? Ich bekomme die Fehlermeldung:

System.ArgumentException: Keyword not supported: 'metadata'.

Michael

07.10.2017 - 12:35 Uhr

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=&quot;data source=***.database.windows.net;initial catalog=***;persist security info=True;user id=***;password=***;multipleactiveresultsets=True;application name=EntityFramework&quot;" providerName="System.Data.EntityClient" />

Was muss ich denn in Azure jetzt als "Name" und "Wert" eintragen ?

Danke
Michael

07.10.2017 - 10:36 Uhr

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

22.08.2017 - 17:38 Uhr

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

15.07.2017 - 17:37 Uhr

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

14.07.2017 - 21:01 Uhr

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

14.07.2017 - 17:18 Uhr

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;
             }
         }
  1. Eine while Schleife bis StatusCode = OK oder
  2. Die Methode aus dem catch heraus nochmal aufrufen ?

Michael

21.06.2017 - 18:13 Uhr

MrSparkle,

auch an Dich ein großes Dankeschön für diesen Hinweis.

Michael

21.06.2017 - 15:54 Uhr

danke inflames2k, das hat mir den Tag gerettet.

Michael

21.06.2017 - 15:13 Uhr

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;
        }

     }
}
21.06.2017 - 14:41 Uhr

an der Fehlermeldung > Fehlermeldung:

der Name db_config ist im aktuellen Kontext nicht vorhanden

Michael

21.06.2017 - 14:29 Uhr

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

18.06.2017 - 16:50 Uhr

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

18.06.2017 - 14:07 Uhr

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

13.06.2017 - 16:16 Uhr

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

03.06.2017 - 10:53 Uhr

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

01.06.2017 - 13:52 Uhr

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

01.06.2017 - 13:36 Uhr

Ja, sorry ... habe ich nochmal geändert.

Michael

01.06.2017 - 13:13 Uhr

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

01.06.2017 - 09:41 Uhr

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

31.05.2017 - 17:45 Uhr

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