使用SelectMany和GroupBy

时间:2017-04-27 14:50:07

标签: c# entity-framework linq linq-to-entities

以下ProjectEnrolment定义项目中的用户及其注册类型:

public class ProjectEnrolment {
  public Project Project { get; set; }
  public User User { get; set; }
  public EnrolmentType EnrolmentType { get; set; }
}

出于测试目的,我需要创建一个ProjectEnrolments列表,其中:
1.每个项目必须有多个ProjectEnrolment;
2.用户不能两次出现在项目中。

我尝试了以下内容:

List<ProjectEnrolment> projectEnrolments = 
  projects.SelectMany(x => 
  users.SelectMany(y => 
  enrolmentTypes.Select(z => 
    new ProjectEnrolment {
      EnrolmentType = z,
      Project = x,
      User = y
    })))          
  .GroupBy(u => u.Project)          
  .Select(v => v.OrderBy(w => Guid.NewGuid()).FirstOrDefault())
  .ToList();  

但这给了我一个ProjectEnrolment每个项目,这不是我需要的。

2 个答案:

答案 0 :(得分:1)

尽管我可能不会在使用SelectMany和其他linq方法的单个指令中执行您想要的操作。这是一个非常复杂的逻辑,最终的指令不可读。怎么样:

Random r = new Random();
IList<ProjectEnrolment> projectEnrolments = new List<ProjectEnrolment>();
foreach (Project project in projects)
{
    int firstUser = r.Next(users.Count);
    projectEnrolments.Add(new ProjectEnrolment {
        EnrolmentType = enrolmentTypes[r.Next(enrolmentTypes.Count)],
        Project = project,
        User = users[firstUser]
    });
    int secondUser;
    do {
        secondUser = r.Next(users.Count);
    } while (secondUser == firstUser);
    projectEnrolments.Add(new ProjectEnrolment {
        EnrolmentType = enrolmentTypes[r.Next(enrolmentTypes.Count)],
        Project = project,
        User = users[secondUser]
    });
}

使用Linq的版本

IList<ProjectEnrolment> projectEnrolments = projects.SelectMany(p => users.OrderBy(u => Guid.NewGuid()).Take(2).Select(u => new ProjectEnrolment {
    EnrolmentType = enrolmentTypes.OrderBy(t => Guid.NewGuid()).FirstOrDefault(),
    Project = p,
    User = u
})).ToList();

答案 1 :(得分:0)

你也可以使用这个 在这里,每个用户都将注册具有随机注册类型的每个项目:

 Random rnd = new Random();
 var res = users.SelectMany(u => projects.Select(p => new ProjectEnrolment() {EnrolmentType = enrollmentTypes[rnd.Next(0, 3)], User = u, Project = p}))
.GroupBy(i => i.Project);