简体   繁体   中英

LINQ Group By Count for Many to Many

I have 2 entities, with a 1 to many relationship, and I'm going to switch it to many to many but I need help with grouping and counts.

SearchString -> many JobResults

A SearchSting is used to find job results and job results are stored as a collection property of 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; }
}

I get the top 5 JobFunctions of all job results as follows:

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();

I'm going to switch it to many to many as such:

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; }
}

How do I get my top 5 jobfunctions counts once I switch it to many to many?

Also, is the structure I chose the right approach? For example I wonder if having jobresults a child collection of SearchString was maybe not the best way to go and that perhaps I should just have SearchStrings be a collection property of JobResult.

For the modified model with many many relationship, consider the following modification to your original query:

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();

Explanation:

  • Now since JobSearchResult contains ICollection<SearchString> , it needs flattening to execute a similar query as earlier
  • SelectMany flattens the data and fills the results as an anonymous type, which contains a record for each SearchString
  • Henceforth similar logic as you have designed is followed

Model Correctness

  • I would not prefer, this kind of relationship, as it makes overall querying and data insertion unnecessarily complex

  • In my understanding a 1 to Many relationship would do as good a job in fetching all the relevant information, in this case you may consider just having ICollection<JobSearchResult> aggregated inside SearchString or vice versa relationship based on suitability, I am not sure what kind of use case does a circular many many relationship model solve.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM