Linq查询微调

时间:2015-09-03 23:30:24

标签: c# linq

查询逻辑是按ID对项目进行分组并按ID排序。然后在分组项目内按Item1排序,然后按Item2排序。

下面的Linq查询,

var group1Items = MyList.GroupBy(g => g.Id)
                        .Where(w => w.Any(a => a.Code = 1)
                        .Select(s => new 
                                    { key = s.Key, 
                                      items = s.OrderBy(o => o.Item1)
                                               .ThenBy(t => t.Item2)
                                     }
                                )
                                .OrderBy(o => o.Id)
                                .SelectMany(sm => sm.Items).ToList();

     var group2Items = MyList.GroupBy(g => g.Id)
                        .Where(w => w.Any(a => a.Code = 2)
                        .Select(s => new 
                                    { key = s.Key, 
                                      items = s.OrderBy(o => o.Item1)
                                               .ThenBy(t => t.Item2)
                                     }
                                )
                                .OrderBy(o => o.Id)
                                .SelectMany(sm => sm.Items).ToList();

   MyList.Clear();
   MyList.InsertRange(Mylist.Count, group1Items);
   MyList.InsertRange(Mylist.Count, group2Items);

在上面的两个查询中,唯一的区别是Where条件。是否可以重写为单个查询?

3 个答案:

答案 0 :(得分:1)

单一查询:

var groupItems = MyList.GroupBy(g => g.Id)
                        .Where(w => w.Any(a => a.Code == 1 || a.Code == 2)
                        .Select(s => new 
                                    { key = s.Key, 
                                      items = s.OrderBy(o => o.Item1)
                                               .ThenBy(t => t.Item2)
                                     }
                                )
                                .OrderBy(o => o.Id)
                                .SelectMany(sm => sm.Items).ToList();

如果代码1必须在代码2之前:

var groupItems = MyList.GroupBy(g => g.Id)
                        .Where(w => w.Any(a => a.Code == 1)
                        .Select(s => new 
                                    { key = s.Key, 
                                      items = s.OrderBy(o => o.Item1)
                                               .ThenBy(t => t.Item2)
                                     }
                                )
                                .OrderBy(o => o.Id)
                                .SelectMany(sm => sm.Items)
                  .Union(MyList.GroupBy(g => g.Id)
                        .Where(w => w.Any(a => a.Code == 2)
                        .Select(s => new 
                                    { key = s.Key, 
                                      items = s.OrderBy(o => o.Item1)
                                               .ThenBy(t => t.Item2)
                                     }
                                )
                                .OrderBy(o => o.Id)
                                .SelectMany(sm => sm.Items)).ToList();

答案 1 :(得分:1)

如果您只想避免代码重复,最简单的方法是捕获一个包含要过滤的代码的变量。

int code = 0;  // initialize with any value
var groupItems = MyList.GroupBy(g => g.Id)
    .Where(w => w.Any(a => a.Code == code)
    .Select(s => new
    {
        key = s.Key,
        items = s.OrderBy(o => o.Item1)
                    .ThenBy(t => t.Item2)
    })
    .OrderBy(o => o.Id)
    .SelectMany(sm => sm.Items);  // No ToList() here!

MyList.Clear();
code = 1;
MyList.InsertRange(Mylist.Count, groupItems.ToList());
code = 2;
MyList.InsertRange(Mylist.Count, groupItems.ToList());

答案 2 :(得分:0)

删除了LINQ表达式中的where子句,并在InsertRange()方法中实现。这可以避免冗余查询

 var groupItems = MyList
                    .GroupBy(g => g.Id)
                    .Select(s => new 
                                { key = s.Key, 
                                  items = s.OrderBy(o => o.Item1)
                                           .ThenBy(t => t.Item2)
                                 }
                            )
                            .OrderBy(o => o.Id)
                            .SelectMany(sm => sm.Items).ToList();


 MyList.Clear();
 MyList.InsertRange(Mylist.Count, groupItems.Where(w => w.Code == 1));
 MyList.InsertRange(Mylist.Count, groupItems.Where(w => w.Code == 2));
相关问题