无法获得使用Linq C#按会话ID分组的调查的最新答案

时间:2016-07-26 16:41:05

标签: c# asp.net-mvc linq session survey

我有一个调查,答案按会话GUID和答案时间戳分组:

public class Answer
{
    [Key]
    public int Id { get; set; }
    public DateTime DateCreated { get; set; }
    public string Session { get; set; }
    public int Numeric { get; set; }
    public string Text { get; set; }
}

如果答案是类型数字(从1到5星),数字将被填充,如果答案是文本类型(如注释),则文本将被填充。

记录示例:

    48  2016-07-15 11:20:14.823 12f68234-fee0-4a3a-88ef-f3977824ed51    5   NULL
    49  2016-07-15 11:20:19.550 12f68234-fee0-4a3a-88ef-f3977824ed51    2   NULL
    50  2016-07-15 11:20:19.553 12f68234-fee0-4a3a-88ef-f3977824ed51    4   NULL
    51  2016-07-15 11:20:19.557 12f68234-fee0-4a3a-88ef-f3977824ed51    3   NULL
    52  2016-07-15 11:20:19.560 12f68234-fee0-4a3a-88ef-f3977824ed51    0   gostei bastante!
    53  2016-07-15 11:59:59.000 a143125e-0463-13f9-fc83-48d660c96156    4   NULL
    54  2016-07-15 12:00:26.277 a143125e-0463-13f9-fc83-48d660c96156    4   NULL
    55  2016-07-15 12:00:26.277 a143125e-0463-13f9-fc83-48d660c96156    3   NULL
    56  2016-07-15 12:00:26.277 a143125e-0463-13f9-fc83-48d660c96156    4   NULL
    57  2016-07-15 12:00:26.297 a143125e-0463-13f9-fc83-48d660c96156    0   Acho que há algumas coisas para melhorar
    58  2016-07-15 17:56:00.503 610821d4-5c48-4222-8c49-c19f0dd9182c    5   NULL
    59  2016-07-15 17:56:16.617 610821d4-5c48-4222-8c49-c19f0dd9182c    5   NULL
    60  2016-07-15 17:56:16.620 610821d4-5c48-4222-8c49-c19f0dd9182c    5   NULL
    61  2016-07-15 17:56:16.617 610821d4-5c48-4222-8c49-c19f0dd9182c    4   NULL
    62  2016-07-15 17:56:16.637 610821d4-5c48-4222-8c49-c19f0dd9182c    0   Gostei bastante de todo o serviço

问题在于我无法按会话分组并按日期命名,因为它们都是不同的记录。

我的代码不起作用是:

var sessions = _dbContext.Answers
    .Where(p => p.Location.Company.Id == id)
    .Where(p => p.Question.Type == QuestionType.Text)
    .Where(p => p.Text != "")
    .OrderByDescending(p => p.DateCreated)
    .Select(p => p.Session)
    .Distinct()
    .Take(count);

    var dto = new List<GetLastCommentsByCountByCompanyIdDTO>();

    foreach (var session in sessions)
    {
        dto.Add(new GetLastCommentsByCountByCompanyIdDTO
        {
            LocationName = _dbContext.Answers.Where(s => s.Session == session).Select(s => s.Location.Name).FirstOrDefault(),
            DateCreated = _dbContext.Answers.Where(s => s.Session == session).Select(s => s.DateCreated).FirstOrDefault(),
            Comment = _dbContext.Answers.Where(s => s.Session == session && s.Question.Type == QuestionType.Text).Select(s => s.Text).FirstOrDefault()
        });
    }

    return dto.OrderByDescending(p => p.DateCreated);                

2 个答案:

答案 0 :(得分:1)

这应该为您提供按会话分组的答案。

var answersGroupedBySession = _dbContext.Answers
                                        .Where(p => p.Location.Company.Id == id 
                                                 && p.Question.Type ==QuestionType.Text
                                                 && p=>!String.IsNullOrEmpty(p.Text))
                                        .GroupBy(g => g.Session, items => items, 
                                                      (key, value) => 
                             new {
                                   Session = key,
                                   Answers = value.OrderByDescending(f => f.DateCreated)
                                 }).ToList();

变量answersGroupedBySession将是具有2个属性Session和Answers的匿名对象列表。对于每个会话,答案将在Answers属性下分组(并按日期排序)。如果您不喜欢匿名对象,可以为此创建一个dto。

public class GroupedAnswers
{
  public string Session {set;get;}
  public IEnumerable<Answer> Answers {set;get;}
}

并在投影部分使用它。

.GroupBy(g => g.Session, items => items, (key, value) => new GroupedAnswers
 {
    Session = key,
    Answers = value.OrderByDescending(f => f.DateCreated)
 }).ToList();

答案 1 :(得分:1)

试试这个:

var baseQuery = _dbContext.Answers.AsNoTracking()
                .Where(p => p.Location.Company.Id == id
                            && p.Question.Type == QuestionType.Text
                            && p.Text != null
                            && p.Text != "")
                .GroupBy(g => new { Session = g.Session, Location = g.Location.Name })
                .Select(x =>
                            new
                            {
                                Session = x.Key.Session,
                                LocationName = x.Key.Location,
                                LastAnswer = x.OrderByDescending(f => f.DateCreated).FirstOrDefault()
                            })
                .Select(x => new GetLastCommentsByCountByCompanyIdDTO
                {
                    LocationName = x.LocationName,
                    DateCreated = x.LastAnswer.DateCreated,
                    Comment = x.LastAnswer.Text
                })
                .OrderByDescending(x => x.DateCreated)
                .Take(count);

            var res = baseQuery.ToList();