Пример #1
0
        /// <summary>
        /// Lädt den XML Export der Datenbank in die Modelklasse.
        /// Vorgegebene Methode, hier ist nichts zu verändern.
        /// </summary>
        /// <param name="filename">Quelldatei</param>
        public void LoadXml(string filename)
        {
            XDocument doc;
            XElement  root;

            try { doc = XDocument.Load(filename); root = doc.Root; }
            catch { return; }

            Tankstellen =
                (from t in root.Elements("Tankstelle")
                 select new Tankstelle
            {
                Id = int.Parse(t.Attribute("Id").Value),
                Bundesland = t.Attribute("Bundesland").Value,
                PLZ = int.Parse(t.Attribute("PLZ").Value),
                Betreiber = t.Attribute("Betreiber").Value,
                Tagespreise =
                    (from tp in t.Elements("Tagespreis")
                     select new Tagespreis
                {
                    Tankstelle = int.Parse(tp.Attribute("Tankstelle").Value),
                    Tag = DateTime.ParseExact(tp.Attribute("Tag").Value, "yyyy-MM-dd", CultureInfo.InvariantCulture),
                    PreisBenzin = decimal.Parse(tp.Attribute("PreisBenzin").Value, CultureInfo.InvariantCulture),
                    PreisDiesel = decimal.Parse(tp.Attribute("PreisDiesel").Value, CultureInfo.InvariantCulture),
                    Verkaeufe =
                        (from v in tp.Elements("Verkauf")
                         select new Verkauf
                    {
                        Id = int.Parse(v.Attribute("Id").Value),
                        Tankstelle = int.Parse(v.Attribute("Tankstelle").Value),
                        Tag = DateTime.ParseExact(v.Attribute("Tag").Value, "yyyy-MM-dd", CultureInfo.InvariantCulture),
                        VerkaufBenzinLiter = v.Attribute("VerkaufBenzinLiter") == null ? (decimal?)null : decimal.Parse(v.Attribute("VerkaufBenzinLiter").Value, CultureInfo.InvariantCulture),
                        VerkaufDieselLiter = v.Attribute("VerkaufDieselLiter") == null ? (decimal?)null : decimal.Parse(v.Attribute("VerkaufDieselLiter").Value, CultureInfo.InvariantCulture),
                        VerkaufShopEuro = v.Attribute("VerkaufShopEuro") == null ? (decimal?)null : decimal.Parse(v.Attribute("VerkaufShopEuro").Value, CultureInfo.InvariantCulture),
                    }).ToList()
                }).ToList()
            }).ToList();

            // Referenzen auf alle Tagespreise und Verkäufe setzen.
            Tagespreise = Tankstellen.SelectMany(t => t.Tagespreise).ToList();
            Verkaeufe   = Tagespreise.SelectMany(tp => tp.Verkaeufe).ToList();

            // Rücknavigationen schreiben.
            foreach (Tagespreis tp in Tagespreise)
            {
                tp._Tankstelle = Tankstellen.FirstOrDefault(t => t.Id == tp.Tankstelle);
            }
            foreach (Verkauf v in Verkaeufe)
            {
                v._Tagespreis = Tagespreise.FirstOrDefault(tp => tp.Tankstelle == v.Tankstelle && tp.Tag == v.Tag);
            }
        }
        /// <summary>
        /// Die zu überschreibende Service-Methode
        /// </summary>
        /// <param name="request">Daten der Anfrage</param>
        /// <param name="responseStream">Der Stream, in den die Ausgabe erfolgen soll</param>
        /// <param name="context"></param>
        /// <returns>Fertigmeldung über Task-Objekt</returns>
        public override async Task Tankstellenpreise(TankstellenpreiseRequest request, IServerStreamWriter <Tankstellen> responseStream, ServerCallContext context)
        {
            // Awaitable anlegen, um die asynchrone Abarbeitung steuern zu können
            var taskCompletionSource = new TaskCompletionSource();

            // max. Anzahl der zu übertragenden Datensätze
            int count = request.Anzahl;

            // Subscription auf das Observable der Tankstellenverwaltung
            using (tankstellenverwaltung.Tankstellen.Subscribe(async liste =>
            {
                try
                {
                    // Prüfen, ob der Stream abgebrochen werden soll
                    context.CancellationToken.ThrowIfCancellationRequested();

                    // Von Protobuf generierte Datenklasse instanzieren und mit den erhaltenen Daten füllen
                    var response = new Tankstellen();
                    response.Liste.AddRange(liste.Select(t => new Tankstelle {
                        Name = t.Name, Super = t.Super, Diesel = t.Diesel
                    }));

                    // Daten über Stream senden
                    await responseStream.WriteAsync(response);

                    count--;
                    if (count <= 0)
                    {
                        // Wenn Anzahl erreicht, kann die Methode kontrolliert beendet werden
                        taskCompletionSource.SetResult();
                    }
                }
                catch (Exception ex)
                {
                    logger.LogError(ex, "Abbruch Grpc-Stream");

                    // Kontrollierter Abbruch der Methode
                    taskCompletionSource.SetResult();
                }
            }))

            {
                // Auf die Fertigstellung der Aufgabe bzw. deren Abbruch warten
                await taskCompletionSource.Task;

                // Subscription wird mit Verlassen des Blocks beendet
            }
        }