我正在建造的东西并不是很独特。简而言之,我正在使用 ASP.NET MVC 4(Web Api)和 Entity Framework 5(具有空间支持)在 Azure 中创建一个类似 FourSquare 的小型服务。所以我使用的是 SQL Azure,而不是像 MongoDB 或 CouchDB 这样的 NoSQL 数据库之一。部分是因为我对 .NET 更流利/熟悉,部分是为了了解开发经验(重构、部署、测试),部分是为了了解它将如何与例如。节点.js/MongoDB。
现在让我们看一些代码。
/// <summary>
/// Return the nearest locations relative from the given longitude/latitude
/// </summary>
/// <param name="longitude">Longitude</param>
/// <param name="latitude">Latitude</param>
/// <param name="maxresults">Optional maximum results, default is 2</param>
/// <param name="radius">Optional maximum radius in kilometres, default is 50 km</param>
/// <returns></returns>
public JsonEnvelope Get(string longitude, string latitude, int maxresults = 2, int radius = 50)
{
    var pointTxt = string.Format("POINT({0} {1})", longitude, latitude);
    var locations = (from s in locationEntityRepository.GetAll
                     orderby s.Coordinates.Distance(DbGeography.FromText(pointTxt))
                     where s.Coordinates.Distance(DbGeography.FromText(pointTxt)) / 1000  <= radius
                     select new Location
                     {
                         Id = s.Id,
                         Name = s.Name,
                         LocationType = s.LocationType,
                         Address = s.Address,
                         Longitude = s.Coordinates.Longitude.Value,
                         Latitude = s.Coordinates.Latitude.Value,
                         Distance = (s.Coordinates.Distance(DbGeography.FromText(pointTxt)).Value) / 1000
                      })
                    .Take(maxresults).ToList();
    // Bad bad bad. But EF/Linq doesn't let us do Includes when using subqueries... Go figure
    foreach (var location in locations)
    {
        location.Checkins = AutoMapper.
                            Mapper.
                            Map<List <Checkin>, List<LocationCheckinsJsonViewModel>>
                                (checkinRepository.GetCheckinsForLocation(location.Id).ToList());
    }
    // AutoMapper.Mapper.Map<Checkin, CheckinViewModel>(dbCheckin);
    var jsonBuilder = new JsonResponseBuilder();
    jsonBuilder.AddObject2Response("locations", locations);
    return jsonBuilder.JsonEnvelope;
}
我认为我需要澄清几件事。locationEntityRepository.GetAll外观是这样的。
public IQueryable<LocationEntity> GetAll
{
    get { return _context.Locations; }
}
public IQueryable<LocationEntity> GetAllIncluding(params Expression<Func<LocationEntity, object>>[] includeProperties)
{
    IQueryable<LocationEntity> query = _context.Locations;
    foreach (var includeProperty in includeProperties) {
        query = query.Include(includeProperty);
    }
    // var tmp = query.ToList();
    return query;
}
现在代码真的闻起来很时髦。理想情况下,我希望能够使用 anGetAllIncluding(c => c.Checkins)而不是该GetAll方法,并且能够用于AutoMapper在 LINQ 投影中进行映射。
我知道在使用子查询时,Include + LINQ/EF 返回 null 是设计使然。在 LINQ/EF 查询中使用 automapper 应该Project().To<>使用.ForMember.
因此,挑战在于使代码更高效(当需要更改我的 JSON 结构时,更少的 SQL 和易于维护。请记住,我们在这里试图击败 node.js/MongoDB ;)我应该打扰还是保留它是?