DbGeography calculation Given the following piece of code, can it be done better:

public object DistanceFrom(
    IEnumerable&lt;Coordinate&gt; coordinates) {
    IEnumerable&lt;DbGeography&gt; addresses = coordinates.Select(
        c =&gt;
            DbGeography.FromText(String.Format("POINT ({0} {1})", c.Longitude, c.Latitude)));
    IEnumerable&lt;VehicleGeography&gt; vehicles = this.GPSInsightProvider.Query().Document.Placemarks.Select(
        p =&gt;
            new VehicleGeography {
                DriverName = p.DriverName,
                Point = DbGeography.FromText(String.Format("POINT ({0} {1})", p.Point.Longitude, p.Point.Latitude))
            });
    ICollection&lt;object&gt; technicians = new List&lt;object&gt;();

    foreach (DbGeography address in addresses) {
        technicians.Add(vehicles.Select(
            v =&gt;
                new {
                    DriverName = v.DriverName,
                    Distance = v.Point.Distance(address) / 1609.344
                }).Where(
            v =&gt;
                v.Distance.HasValue).OrderBy(
            v =&gt;
                v.Distance).Take(3).Select(
            v =&gt;
                new {
                    DriverName = v.DriverName,
                    Distance = String.Format("{0:#.#}", v.Distance)
                }));
    }

    return technicians;
}


GPSInsightProvider parses a KML and returns its object representation. I then take that and convert it temporarily into a VehicleGeography so I can create a DbGeography property for it. I then loop through the addresses I'm checking against and the do a dirty-looking calculation to see which are the closest three vehicles to the address. At most I will be doing this for a maximum of three addresses at a time. I take the resulting object and return it as JSON to my web application.

I'm curious if there's a better way to perform that whole lookup/calculation/whatever-this-is?
Firstly, I really don't like your indentation, particularly with the method header, so I've pasted into Visual Studio and will be working from the code as it appears below:

    public object DistanceFrom(IEnumerable&lt;Coordinate&gt; coordinates)
    {
        IEnumerable&lt;DbGeography&gt; addresses = coordinates.Select(c =&gt;
            DbGeography.FromText(String.Format("POINT ({0} {1})", c.Longitude, c.Latitude)));
        IEnumerable&lt;VehicleGeography&gt; vehicles = this.GPSInsightProvider.Query().Document.Placemarks.Select(p =&gt;
            new VehicleGeography
            {
                DriverName = p.DriverName,
                Point = DbGeography.FromText(String.Format("POINT ({0} {1})", p.Point.Longitude, p.Point.Latitude))
            });
        ICollection&lt;object&gt; technicians = new List&lt;object&gt;();

        foreach (DbGeography address in addresses)
        {
            technicians.Add(
                vehicles
                    .Select(v =&gt;
                        new
                        {
                            DriverName = v.DriverName,
                            Distance = v.Point.Distance(address) / 1609.344
                        })
                    .Where(v =&gt;v.Distance.HasValue)
                    .OrderBy(v =&gt;v.Distance)
                    .Take(3)
                    .Select(v =&gt;
                        new
                        {
                            DriverName = v.DriverName,
                            Distance = String.Format("{0:#.#}", v.Distance)
                        }));
        }

        return technicians;
    }


My first question: Why does this return an object? I'm strongly against returning anonymous types, you really should be creating a class or struct for this data combination. Secondly, you know that at the bare minimum, it returns a List of these anonymous types, so at the least your should return a List&lt;object&gt;

Secondly:

ICollection&lt;object&gt; technicians = new List&lt;object&gt;();

Why are you specifically reducing the functionality that you're returning? Require least on parameters, return most.

Use var on variable declarations where the right-hand-side makes the type obvious. This saves you extra typing when you want to change that variable's type later.

e.g.

ICollection&lt;object&gt; technicians = new List&lt;object&gt;();

becomes

var technicians = new List&lt;object&gt;();

Is there a special reason you return only the top 3 results from your query? If so, that magic number should be a const somewhere with a reasonable name. If not, it should be a variable somewhere, again with a reasonable name.

The same goes for 1609.344. I'm guessing that's a conversion from meters to miles, but it doesn't make a ton of sense on its own.

I think your LINQ is doing a little bit too much. I'd recommend splitting it up a bit so it's clearer what it's doing. Afterall, you're already looping through addresses, so split it up a little.

            technicians.Add(
                vehicles
                    .Select(v =&gt;
                        new
                        {
                            DriverName = v.DriverName,
                            Distance = v.Point.Distance(address) / 1609.344
                        })
                    .Where(v =&gt;v.Distance.HasValue)
                    .OrderBy(v =&gt;v.Distance)
                    .Take(3)
                    .Select(v =&gt;
                        new
                        {
                            DriverName = v.DriverName,
                            Distance = String.Format("{0:#.#}", v.Distance)
                        }));


maybe becomes

            var vehiclesByDistance = 
                vehicles
                    .Select(v =&gt;
                        new
                        {
                            DriverName = v.DriverName,
                            Distance = v.Point.Distance(address) / 1609.344
                        })
                    .Where(v =&gt;v.Distance.HasValue)
                    .OrderBy(v =&gt;v.Distance);

            technicians.Add(
                vehiclesByDistance
                    .Take(3)
                    .Select(v =&gt;
                        new
                        {
                            DriverName = v.DriverName,
                            Distance = String.Format("{0:#.#}", v.Distance)
                        }));


Finally, I'm pretty sure your LINQ is breaking the Single Responsibility Principle. It appears to be performing distance unit conversion, sorting and formatting. It might be wise to split this up a bit.