Jef*_*ume 9 c# linq entity-framework
使用实体框架6.0.2和.NET 4.5.1在Visual Studio中2013更新1与DbContext
连接到SQL Server:
我有一长串过滤器,我根据调用者的期望结果应用于查询.一切都很好,直到我需要添加分页.这是一瞥:
IQueryable<ProviderWithDistance> results = (from pl in db.ProviderLocations
let distance = pl.Location.Geocode.Distance(_geo)
where pl.Location.Geocode.IsEmpty == false
where distance <= radius * 1609.344
orderby distance
select new ProviderWithDistance() { Provider = pl.Provider, Distance = Math.Round((double)(distance / 1609.344), 1) }).Distinct();
if (gender != null)
{
results = results.Where(p => p.Provider.Gender == (gender.ToUpper() == "M" ? Gender.Male : Gender.Female));
}
if (type != null)
{
int providerType;
if (int.TryParse(type, out providerType))
results = results.Where(p => p.Provider.ProviderType.Id == providerType);
}
if (newpatients != null && newpatients == true)
{
results = results.Where(p => p.Provider.ProviderLocations.Any(pl => pl.AcceptingNewPatients == null || pl.AcceptingNewPatients == AcceptingNewPatients.Yes));
}
if (string.IsNullOrEmpty(specialties) == false)
{
List<int> _ids = specialties.Split(',').Select(int.Parse).ToList();
results = results.Where(p => p.Provider.Specialties.Any(x => _ids.Contains(x.Id)));
}
if (string.IsNullOrEmpty(degrees) == false)
{
List<int> _ids = specialties.Split(',').Select(int.Parse).ToList();
results = results.Where(p => p.Provider.Degrees.Any(x => _ids.Contains(x.Id)));
}
if (string.IsNullOrEmpty(languages) == false)
{
List<int> _ids = specialties.Split(',').Select(int.Parse).ToList();
results = results.Where(p => p.Provider.Languages.Any(x => _ids.Contains(x.Id)));
}
if (string.IsNullOrEmpty(keyword) == false)
{
results = results.Where(p =>
(p.Provider.FirstName + " " + p.Provider.LastName).Contains(keyword));
}
Run Code Online (Sandbox Code Playgroud)
这是我添加到底部的分页(skip
并且max
只是int参数):
if (skip > 0)
results = results.Skip(skip);
results = results.Take(max);
return new ProviderWithDistanceDto { Locations = results.AsEnumerable() };
Run Code Online (Sandbox Code Playgroud)
现在我的问题:
正如你所看到的,我在最初的LINQ查询中做了一个orderby,所以为什么在做一个OrderBy
之前我需要做一个Skip
(我以为我是?)...
我假设它不会被转换为SQL查询并执行,直到我枚举结果,这就是为什么我等到最后一行返回结果AsEnumerable().这是正确的方法吗?
如果非要列举前做的结果Skip
以及Take
这将如何影响性能?显然,我想让SQL Server完成繁重的工作,只返回请求的结果.或者没关系(或者我弄错了)?
das*_*ght 11
我在最初的LINQ查询中做了一个orderby,所以为什么在做Skip之前我需要做一个OrderBy(我以为我是?)
您result
作为有序可查询对象正确启动:从第一行查询返回的类型是IOrderedQueryable<ProviderWithDistance>
,因为您有一个order by
子句.但是,Where
在它上面添加一个使您的查询IQueryable<ProviderWithDistance>
再次成为普通查询,从而导致您看到的问题.从逻辑上讲,这是一回事,但内存中查询定义的结构意味着其他方面.
要解决此问题,请删除order by
原始查询中的内容,然后在准备好进行分页之前添加它,如下所示:
...
if (string.IsNullOrEmpty(languages) == false)
...
if (string.IsNullOrEmpty(keyword) == false)
...
result = result.OrderBy(r => r.distance);
Run Code Online (Sandbox Code Playgroud)
只要排序是最后一个操作,这应该解决运行时问题.
我假设它不会被转换为SQL查询并执行,直到我枚举结果,这就是为什么我等到最后一行返回结果
AsEnumerable()
.这是正确的方法吗?
是的,这是正确的方法.您希望您的RDBMS尽可能多地工作,因为在内存中进行分页会首先破坏分页的目的.
如果我在做Skip之前必须枚举结果,那么它将如何影响性能?
它会破坏性能,因为系统需要移动比添加分页之前更多的数据.
归档时间: |
|
查看次数: |
10063 次 |
最近记录: |