搜索包含大量列的表,然后使用EntityFramework对结果进行分组

时间:2014-11-09 17:25:46

标签: c# asp.net asp.net-mvc entity-framework

我有一个Asp.Net MVC 5网站,我首先使用Entity Framework代码访问其数据库。我有一个Restaurants表,我想让用户用很多参数搜索这些表。这是我到目前为止所做的:

public void FilterModel(ref IQueryable<Restaurant> model)
{
    if (!string.IsNullOrWhiteSpace(RestaurantName))
    {
        model = model.Where(r => r.Name.ToUpper().Contains(RestaurantName));
    }

    if (Recommended)
    {
        model = model.Where(r => r.SearchSponsor);
    }

    //...
}

基本上我会查找每个属性,并在链中添加另一个Where,如果它不是空的。

之后,我想根据一些标准对结果进行分组。我现在正在这样做:

private static IQueryable<Restaurant> GroupResults(IQueryable<Restaurant> model)
{
    var groups = model.GroupBy(r => r.Active);
    var list = new List<IGrouping<bool, Restaurant>>();
    foreach (var group in groups)
    {
        list.Add(group);
    }

    if (list.Count < 1)
    {
        SortModel(ref model);
        return model;
    }

    IQueryable<Restaurant> joined, actives, inactives;
    if (list[0].FirstOrDefault().Active)
    {
        actives = list[0].AsQueryable();
        inactives = list.Count == 2 ? list[1].AsQueryable() : null;
    }
    else
    {
        actives = list.Count == 2 ? list[1].AsQueryable() : null;
        inactives = list[0].AsQueryable();
    }

    if (actives != null)
    {
        //....
    }

    if (inactives != null)
    {
        SortModel(ref inactives);
    }

    if (actives == null || inactives == null)
    {
        return actives ?? inactives;
    }

    joined = actives.Union(inactives).AsQueryable();

    return joined;
}

这有效,但它有很多并发症,为了保持这个小问题,我宁愿不谈。

我想知道这是否是正确而有效的方法。看起来有点“脏”!很多ifWhere s。存储过程,倒排索引等。这是我的第一个“大”项目,我想从你的经验中学习以“正确”的方式做到这一点。

2 个答案:

答案 0 :(得分:1)

查看GroupResults方法我对你正在做的事情感到有些困惑。似乎打算收到一份任意的餐馆名单,并返回按活动和其他一些标准订购的餐馆的有序清单。 如果这是真的,你可以做这样的事情并完成你的工作:

model.OrderBy(x => x.Active).ThenBy(x => Name);

如果SortModel在某种程度上更复杂,您可以在语句中添加一个比较器,或者坚持使用当前的解决方案,但将其更改为:

if (model == null || !model.Any())
{
    return model;
}
var active = model.Where(x=>x.Active);
var inactives = model.Where(x=>!x.Active);
// if (inactives == null) //not needed as where always return at least an empty list. Mabye check for inactive.Any()
SortModel(ref inactives); //You may also remove the ref as it's an reference anyway
joined = actives.Union(inactives).AsQueryable();
return joined;

答案 1 :(得分:1)

关于您处理搜索的方式,我认为它很简单,易于阅读和理解,并且有效。新的团队成员将能够查看该代码并立即知道它正在做什么以及它是如何工作的。我认为这是一个非常好的迹象,表明你的方法是合理的。