使用列表、匿名类型和Suchlike

本文关键字:类型 Suchlike 列表 | 更新日期: 2023-09-27 17:58:43

根据前面的问题,我现在有一个匿名类型的集合

[用户:用户名(作为CCD_ 1,用户ID]。

此"用户"集合最终需要绑定到下拉列表。这很好,但我需要做的是按姓氏和名字对它们进行排序。但由于用户名格式是forename.surname.,这就变得复杂了

在高层,这将涉及字符串上的Split,以分离名称组件,然后ToTitleCase()两个部分,然后将新值存储在列表中的另一个对象中,然后我可以使用List<T>.OrderBy(...).ThenBy(...) 对其进行排序

我突然想到,我正在尝试学习的所有这些新奇的新语法可能包括在几行简洁的代码中执行这个过程的方法。有人能证实或否认这一点吗?

谢谢。

编辑3:

我想我已经破解了:

var salesusers =    (
                      from s in lstReport 
                      group s by new { s.SalesUserId,s.Username} 
                      into g
                      select new
                          {
                             Username = g.Key.Username.Split('.')[1].ToTitleCase() + " " + g.Key.Username.Split('.')[0].ToTitleCase(),
                             Surname = g.Key.Username.Split('.')[1].ToTitleCase(),
                             Forename = g.Key.Username.Split('.')[0].ToTitleCase(),
                             UserId = g.Key.SalesUserId 
                           }
                     ).OrderBy(a=> a.Surname).ThenBy(a=> a.Forename);

我需要从用户名中创建单独的名字和姓氏字段以进行排序,并从用户名中绑定到下拉列表。这看起来很疯狂,但效果很好,我现在还是坚持下去。非常感谢您的评论。

第2版:所以我做到了这一点。现在我想知道语法是否允许我将前面问题中的Group by操作与此步骤结合起来。。

var sortedUsers = from u in salesusers
                  orderby u.UserName.Split('.')[1], u.UserName.Split('.')[0]
                  select new {UserName = u.UserName.Replace(".", " ").ToTitleCase(), UserId = u.UserId.Value};

有人。。。?

编辑:我自己完成了所有的大部分,以防有人需要,但事实证明,在订购过程中转换名称组件ToTitleCase很困难。

此:

var sortedUsers = from u in salesusers
                  orderby u.UserName.Split('.')[1], u.UserName.Split('.')[0]
                  select u;

似乎做到了技巧除了ToTitleCase ing之外,我需要的一切。但当然,可能有一种更快/更简洁/更优雅的方法,所以我会把它放一两天,看看结果如何;-)

使用列表、匿名类型和Suchlike

使用lambdas而不是表达式语法可以实现更少的代码,因此

var sorted = salesusers.OrderBy(u => u.UserName.Split('.')[1]).ThenBy(u => u.UserName.Split('.')[0]).ToList();

虽然它的可读性较差,但一旦你习惯了语法,我发现它比表达式语法更容易阅读。

编辑:编辑3 的更改

您的代码转换为Lambdas如下

var salesusers = (l.GroupBy(s => new { SalesUserId = s.SalesUserId, Username = s.Username }).Select(g =>new {
                                Username = g.Key.Username.Split('.')[1].ToTitleCase() + " " + g.Key.Username.Split('.')[0].ToTitleCase(),
                                Surname = g.Key.Username.Split('.')[1].ToTitleCase(),
                                Forename = g.Key.Username.Split('.')[0].ToTitleCase(),
                                UserId = g.Key.SalesUserId
                    })).OrderBy(a => a.Surname).ThenBy(a => a.Forename);

唯一的问题是,表达式越大,就越难阅读!

另一种读起来更干净的方法是定义细节对象,而不是使用动态对象。

internal class UserDetails
    {
        public UserDetails(User u)
        {
            this.Forename = u.Username.Split('.')[0].ToTitleCase();
            this.Surname = u.Username.Split('.')[1].ToTitleCase();
            this.UserId = u.SalesUserId;
            this.Username = u.Username;
        }
        public string Username { get; set; }
        public string Surname { get; set; }
        public string Forename { get; set; }
        public int UserId { get; set; }
    }

然后你可以做

var salesusers = (l.GroupBy(s => new { SalesUserId = s.SalesUserId, Username = s.Username })
    .OrderBy(u => u.Username.Split('.')[1].ToTitleCase())
    .ThenBy(u => u.Username.Split('.')[0].ToTitleCase())
    .Select(g => new UserDetails(g)));

但这是更多的代码,我不确定你是否想要。

最新编辑:

你的代码不需要按语句分组,所以你可以通过来减少这种情况

 var salesusers = (
                    from s in l
                        select new
                        {
                            Username = s.Username.Split('.')[1].ToTitleCase() + " " + s.Username.Split('.')[0].ToTitleCase(),
                            Surname = s.Username.Split('.')[1].ToTitleCase(),
                            Forename = s.Username.Split('.')[0].ToTitleCase(),
                            UserId = s.SalesUserId
                        }
                 ).OrderBy(a => a.Surname).ThenBy(a => a.Forename);

或者使用Lambdas成为

var salesusers = l.Select(g =>new {
                            Username = g.Username.Split('.')[1].ToTitleCase() + " " + g.Username.Split('.')[0].ToTitleCase(),
                            Surname = g.Username.Split('.')[1].ToTitleCase(),
                            Forename = g.Username.Split('.')[0].ToTitleCase(),
                            UserId = g.SalesUserId
                }).OrderBy(a => a.Surname).ThenBy(a => a.Forename);

除此之外,我能看到的进一步减少调用的唯一方法是使用上面定义的类,这并不是说它不能完成!但我不知道怎么回事!

HTH-

OneShot

这是我提出的最终解决方案-它对ToTitleCase s和格式进行排序。如果我自己这么说的话,那就太漂亮了。花了我一上午的时间

var salesusers =    (
                        from s in lstReport 
                        group s by new { s.SalesUserId,s.Username} 
                        into g
                        select new
                            {
                                Username = g.Key.Username.Split('.')[1].ToTitleCase() + " " + g.Key.Username.Split('.')[0].ToTitleCase(),  
                                Surname = g.Key.Username.Split('.')[1].ToTitleCase(),  
                                Forename = g.Key.Username.Split('.')[0].ToTitleCase(),  
                                UserId = g.Key.SalesUserId 
                             }  
                     ).OrderBy(a=> a.Surname).ThenBy(a=> a.Forename);