LINQ Group By Count for Many to Many

时间:2016-10-30 04:59:06

标签: c# linq

我有2个实体,有1对多的关系,我会将其切换为多对多,但我需要帮助进行分组和计数。

SearchString - >许多JobResults

SearchSting用于查找作业结果,作业结果存储为SearchString的集合属性:

public class SearchString
{
    public int SearchStringId { get; set; }
    public string SearchStringName { get; set; }
    public string query { get; set; }
    public JobFunction JobFunction { get; set; }
    public JobSeniority JobSeniority { get; set; }
    public virtual ICollection<JobSearchResult> results { get; set; }
}
public class JobSearchResult
{        
    public int JobSearchResultId { get; set; }
    public string jobtitle { get; set; }
    public string company { get; set; }
    public virtual SearchString SearchString { get; set; }
}

我得到所有工作结果的前5个JobFunction,如下所示:

var top5jobfunctions = JobSearchResults.Where(a => (a.SearchString != null)).
            GroupBy(s => new { s.SearchString.JobFunction.JobFunctionId, s.SearchString.JobFunction.JobFunctionName }).
            Select(g => new { value = g.Key.JobFunctionId, displayname = g.Key.JobFunctionName, count = g.Count() }).
            OrderByDescending(x => x.count).
            Take(5).ToList();

我会将其切换为多对多:

public class SearchString
{
    public int SearchStringId { get; set; }
    public string SearchStringName { get; set; }
    public string query { get; set; }
    public JobFunction JobFunction { get; set; }
    public JobSeniority JobSeniority { get; set; }
    public virtual ICollection<JobSearchResult> results { get; set; }
}
public class JobSearchResult
{        
    public int JobSearchResultId { get; set; }
    public string jobtitle { get; set; }
    public string company { get; set; }
    public virtual ICollection<SearchString> SearchStrings { get; set; }
}

一旦我将其转换为多对多,我如何才能获得前5个职务?

另外,我选择正确方法的结构是什么?例如,我想知道如果有一个搜索结果的子集合可能不是最好的方法,也许我应该让SearchStrings成为JobResult的集合属性。

1 个答案:

答案 0 :(得分:1)

对于具有许多关系的修改模型,请考虑对原始查询进行以下修改:

var top5jobfunctions = 
  JobSearchResults.SelectMany(j => j.SearchString.Select(s => new {j,s}))
                  .Where(j => (j.s != null))
                  .GroupBy(j => new { j.s.JobFunction.JobFunctionId, j.s.JobFunction.JobFunctionName })
                  .Select(g => new { value = g.Key.JobFunctionId, displayname = g.Key.JobFunctionName, count = g.Count() })
                  .OrderByDescending(x => x.count)
                  .Take(5).ToList();

<强>解释

  • 由于JobSearchResult包含ICollection<SearchString>,因此需要展平才能执行与之前类似的查询
  • SelectMany展平数据并将结果填充为匿名类型,其中包含每个SearchString的记录
  • 此后,您遵循的逻辑与
  • 相似

模型正确性

  • 我不喜欢这种关系,因为它会使整体查询和数据插入变得不必要地复杂

  • 在我的理解中,1对多关系在获取所有相关信息方面做得很好,在这种情况下,您可以考虑将ICollection<JobSearchResult>聚合在SearchString内,反之亦然基于适用性的关系,我不确定循环很多关系模型解决了什么样的用例。