你知道另一种方法吗;巨大的“;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();

因此,正如您所看到的,我执行一些查询,存储从用户中选择的值。然后,对于每一排酒店,我骑着城市和类别的阵列。

这个,有很多排,它是非常昂贵的。

你知道优化研究的其他方法吗?

你知道另一种方法吗;巨大的“;linq滤波

将您的城市和类别放入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,则必须以另一种方式进行过滤。。。也许是通过传递.

中的标准列表