你知道另一种方法吗;巨大的“;linq滤波
本文关键字:巨大 linq 滤波 另一种 方法 | 更新日期: 2023-09-27 18:27:06
这是我的代码:
// I STORE THE USER SELECTED VALUES
IList<string> SelectedCity = (from CheckBox loc in panelCity.Controls.OfType<CheckBox>()
where loc.Checked
select loc.InputAttributes["value"]).ToList();
IList<string> SelectedCategories = (from CheckBox strut in panelCategories.Controls.OfType<CheckBox>()
where strut.Checked
select strut.InputAttributes["value"]).ToList();
// I GET ALL RECORDS
IList<Hotel> Hotels = (from Hotel hotel in new Hotels()
orderby hotel.Titolo ascending
select hotel).ToList();
// I FILTER THEM
if (SelectedCity.Count > 0)
Hotels = Hotels.Where(o => o.City != null && SelectedCity.Contains(o.City.UniqueID)).ToList();
if (SelectedCategories.Count > 0)
Hotels = Hotels.Where(o => o.Category != null && SelectedCategories.Contains(o.Category.UniqueID)).ToList();
因此,正如您所看到的,我执行一些查询,存储从用户中选择的值。然后,对于每一排酒店,我骑着城市和类别的阵列。
这个,有很多排,它是非常昂贵的。
你知道优化研究的其他方法吗?
将您的城市和类别放入HashSet<string>
以节省查找时间:
HashSet<string> selectedCities = new HashSet<string>(SelectedCity);
HashSet<string> selectedCategories = new HashSet<string>(SelectedCategories);
此外,在查询完全组装好之前,您不需要使用ToList()
,否则您将遍历多次:
var hotels = from Hotel hotel in new Hotels()
select hotel;
if (SelectedCity.Any())
hotels = hotels.Where(o => o.City != null && selectedCities.Contains(o.City.UniqueID));
if (SelectedCategories.Any())
hotels = hotels.Where(o => o.Category != null && selectedCategories.Contains(o.Category.UniqueID));
最后,一旦你过滤掉所有你不想要的酒店,就可以进行分类,这样你就可以减少分类项目:
hotels = hotels.OrderBy(h=> h.Titolo);
作为实现结果的最后一步:
Hotels = hotels.ToList();
至少,您可以将Where子句组合到上面的Linq语句中:
IList Hotels=(来自新Hotels中的酒店酒店)其中SelectedCity.Count>0&&酒店。城市!=null&&SelectedCity.Contains(hotel.City.UniqueID)其中SelectedCategories.Count>0&&hotel。类别!=null&&SelectedCategories.Contains(hotel.Category.UniqueID)按酒店订购。Titolo上升选择酒店).ToList()
这里只是猜测,但最大的成功似乎是获得所有酒店,因为您只需要城市或类别就可以进行后续查询。
如果你只选择所需的输入来获得匹配的Id,那么选择匹配的酒店可能会有所改善。
将所有酒店加载到内存中进行搜索是非常无效的;但是,如果您没有加载所有酒店,您将无法调用集合中的Contains()
。相反,您可以使用Joseph Albahari网站的PredicateBuilder
来构建一个谓词,该谓词可以用于仅获取符合条件的酒店。
var inSelectedCities = PredicateBuilder.True<Hotel>();
foreach(var city in SelectedCity)
{
string temp = city;
inSelectedCities = inSelectedCities.Or(h => h.City.UniqueId == temp);
}
var inSelectedCategories = PredicateBuilder.True<Hotel>();
foreach(var category in SelectedCategories)
{
string temp = category;
inSelectedCategories = inSelectedCategories.Or(h => h.Category.UniqueId == temp)
}
var hotels = Hotels
.Where(inSelectedCities.Or(inSelectedCategories))
.ToList();
性能问题显然出在Hotels构造函数中,该构造函数会访问数据库。如果该构造函数使用LinqToSql或LinqToEntities,则应将Expression<Func<Hotel, bool>>
传递到其中,以便从Queryable.Where
进行调用,并在数据库端进行一些筛选。
如果该构造函数不使用Linq,则必须以另一种方式进行过滤。。。也许是通过传递.