【问题标题】:Extract a method from two, almost identical, Linq queries从两个几乎相同的 Linq 查询中提取方法
【发布时间】:2017-02-10 16:02:15
【问题描述】:

我正在尝试重构一个类,该类从数据库中提取一些 QuerySuggest 类型的对象。使用 Linq 对从 DB 返回的对象进行两次查询。

很明显,这两个查询几乎相同,唯一的区别是前者我有一个附加条件:“ && e.UserId == request.UserId”。

这在我看来是一种代码味道,我想重构它,但我不确定如何进行。

这是我需要重构的代码示例:

IRepository<QuerySuggest> repository = _repositoryManager.GetRepository<QuerySuggest>(_repositoryType);

        //entitiesByUser contains all the query suggest by the user
        var entitiesByUser = repository.Query(c => c.Where(e => e.IdWebsite == request.WebSiteId &&
                                                        e.FulltextFree != null &&
                                                        e.DataOra >= (System.DateTime.Today.AddDays(-60).Date) &&
                                                        e.UserId == request.UserId)
                                                .GroupBy(g => g.FulltextFree)
                                                .Select(n => new { FulltextFree = n.Key, HowMany = n.Count() })
                                                .Where(w => w.HowMany >= request.HowMany)
                                                .OrderBy(o => o.HowMany))
                                                .ToList();
        //entitiesByUser contains all the query suggest not from user
        var nonUserEntities = repository.Query(c => c.Where(e => e.IdWebsite == request.WebSiteId &&
                                                        e.FulltextFree != null &&
                                                        e.DataOra >= (System.DateTime.Today.AddDays(-60).Date))
                                                .GroupBy(g => g.FulltextFree)
                                                .Select(n => new { FulltextFree = n.Key, HowMany = n.Count() })
                                                .Where(w => w.HowMany >= request.HowMany)
                                                .OrderBy(o => o.HowMany))
                                                .ToList();

【问题讨论】:

  • request 在这两种情况下是同一种类型吗?
  • 是的,是同一类型

标签: c# linq


【解决方案1】:

我相信这应该是一种方法:

IList<QuerySuggest> QuerySuggestions(
    RequestType request, 
    bool filterByUser = false,
    bool excludeUser = false)
{
    IRepository<QuerySuggest> repository = 
        _repositoryManager.GetRepository<QuerySuggest>(_repositoryType);

    var entities = repository
        .Query(c => c.Where(e => 
            e.IdWebsite == request.WebSiteId &&
            e.FulltextFree != null &&
            e.DataOra >= (System.DateTime.Today.AddDays(-60).Date) &&
            (!filterByUser || e.UserId == request.UserId) &&
            (!excludeUser || e.UserId != request.UserId)
        )
        .GroupBy(g => g.FulltextFree)
        .Select(n => new { FulltextFree = n.Key, HowMany = n.Count() })
        .Where(w => w.HowMany >= request.HowMany)
        .OrderBy(o => o.HowMany))
        .ToList();

    return entities;
}

IList<QuerySuggest> QuerySuggestionsByUser(RequestType request)
{
    return QuerySuggestions(request, filterByUser: true);
}

IList<QuerySuggest> QuerySuggestionsAnyUser(RequestType request)
{
    return QuerySuggestions(request);
}

IList<QuerySuggest> QuerySuggestionsOtherUsers(RequestType request)
{
    return QuerySuggestions(request, excludeUser: true);
}

【讨论】:

  • 如果我需要在一种情况下使用e.UserId == request.UserId 而在另一种情况下使用e.UserId != request.UserId 怎么办?逻辑表达式不再有效,我尝试了许多不同的表达式都没有成功
  • @davideAlbertini 在上面做了更新。请试一试。
【解决方案2】:

您可以编写一个组合谓词的方法。 @Jon Skeet 在这里提供了两种这样的方法:

Combine Multiple Predicates

你应该可以像这样使用它们:

Predicate<YourType> a = e => e.IdWebsite == request.WebSiteId &&
                                            e.FulltextFree != null &&
                                            e.DataOra >= (System.DateTime.Today.AddDays(-60).Date);

Predicate<YourType> b = e => e.UserId == request.UserId;

var entitiesByUser = repository.Query(c => c.Where(Helpers.And(a, b)));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-27
    相关资源
    最近更新 更多