gpt4 book ai didi

c# - 使用空间类型和自动映射器时如何优化 Entity Framework 查询?

转载 作者:行者123 更新时间:2023-11-30 17:06:45 25 4
gpt4 key购买 nike

我正在构建的并不是非常独特的东西。简而言之,我正在使用 ASP.NET MVC 4(Web Api)和 Entity Framework 5(具有空间支持)创建一个类似 FourSquare 的小型服务,该服务在 Azure 中运行。所以我使用的是 SQL Azure,而不是像 MongoDB 或 CouchDB 这样的 NoSQL 数据库之一。部分是因为我更流利/熟悉 .NET,部分是为了了解开发体验(重构、部署、测试),部分是为了了解它如何与 .NET 相媲美。 node.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;
}

现在代码真的很奇怪。理想情况下,我希望能够使用 GetAllIncluding(c => c.Checkins)而不是 GetAll方法,并能够使用 AutoMapper在 LINQ 投影内进行映射。

我知道在使用子查询时,Include + LINQ/EF 会按设计返回 null。在 LINQ/EF 查询中使用自动映射器应该使用 Project().To<> 来完成, 但在使用 .ForMember 时不起作用.

所以挑战在于使代码更高效(更少的 SQL 并且在需要更改我的 JSON 结构时易于维护。请记住,我们试图在这里击败 node.js/MongoDB ;)我应该打扰,还是保持原样?

最佳答案

我使用 Repository 模式做了类似的事情。

    public IEnumerable<T> FindAll()
{
return _context.Set<T>().ToList();
}

public IEnumerable<T> FindBy(Expression<Func<T, bool>> predicate)
{
return _context.Set<T>().Where(predicate);
}

.Set方法在哪里

    public IDbSet<TEntity> Set<TEntity>() where TEntity : class
{
return base.Set<TEntity>();
}

这允许您从数据库中获取某种类型的所有内容,或者只获取满足特定条件的所有类型。

这会给您留下一个对象列表,或者如果您使用 FirstOrDefault() 一个单独的对象,您可以根据需要映射它。

关于c# - 使用空间类型和自动映射器时如何优化 Entity Framework 查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15222649/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com