6
\$\begingroup\$

I'm loading three kinds of entities from an API (in csv format unfortunately). While the first two are fine, the third has foreign keys to both of them. What I'm currently doing is constructing the first two lists and then while constructing the third list I assign the entities for every item. This is how it looks:

var platforms = await Task.Run(() => parsed.Data.Select(p => CreatePlatform(p,stations,lines)).ToList());

private static Platform CreatePlatform(Dictionary<string, string> data, List<Station> stations, List<Line> lines)
    {
        if (data.Keys.Except(PlatformFields).Any())
            return null; // TODO log; invalid data format
        Platform platform = null;
        try
        {
            platform = new Platform
            {
                SteigId = Convert.ToInt32(data["STEIG_ID"]),
                Richtung = data["RICHTUNG"],
                Reihenfolge = Convert.ToInt32(data["REIHENFOLGE"]),
                RblNummer = string.IsNullOrEmpty(data["RBL_NUMMER"]) ? null : (int?) Convert.ToInt32(data["RBL_NUMMER"]),
                Bereich = string.IsNullOrEmpty(data["BEREICH"])? null : (int?) Convert.ToInt32(data["BEREICH"]),
                Steig = data["STEIG"],
                SteigWgs84Lat = Convert.ToDouble(data["STEIG_WGS84_LAT"]),
                SteigWgs84Lon = Convert.ToDouble(data["STEIG_WGS84_LON"]),
                Stand = data["STAND"],

                Station = stations.Single(s => s.HaltestellenId == Convert.ToInt32(data["FK_HALTESTELLEN_ID"])),
                Line = lines.Single(l => l.LinienId == Convert.ToInt32(data["FK_LINIEN_ID"]))

            };
        }
        catch (FormatException ex)
        {
            return null; // TODO log;
        }
        return platform;
    }

Stations and Lines are sets that have been constructed in the exact same way (only without fk's). Hirarchy-wise I want the Stations to include a list of plattforms and each platform has the corresponding line. I also get this using the current method as entity framework handles the dependencies.

My problem is that this method of runnig two selects for every Platform item takes multiple seconds and i'm using this data for input suggestions which i'd like to be available as soon as possible

Is there a more efficient way of assigning the correct dependencies?

If there's some important information missing please tell me

\$\endgroup\$
  • \$\begingroup\$ if you are sure that stations and lines contain no more then one appropriate item then First instead of Singlewill give you better performance \$\endgroup\$ – Disappointed Jul 22 '16 at 10:34
6
\$\begingroup\$

Using .Single() on an unsorted list has O(n) cost. If you use a data structure with constant time lookups e.g. a Dictionary<int, Station> and a Dictionary<int, Line> instead you should see a performance improvement using key lookup:

Station = stations[Convert.ToInt32(data["FK_HALTESTELLEN_ID"])],
Line = lines[Convert.ToInt32(data["FK_LINIEN_ID"])]

As you're using Single, I assumed that the dictionary will definitely contain the entry.

I don't know how you're creating your Lists but there is the Enumerable.ToDictionary method which could be useful:

var stationsLookup = stations.ToDictionary(s => s.HaltestellenId);
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.