SELECT和WHERE LINQ子句可以组合吗?

Bla*_*ise 2 c# linq

以下是我对Select用户进入模型的所有操作,然后删除所有null记录:

        model.Users = users
            .Select(u =>
        {
            var membershipUser = Membership.GetUser(u.UserName);
            return membershipUser != null
                ? new UserBriefModel
                {
                    Username = u.UserName,
                    Fullname = u.FullName,
                    Email = membershipUser.Email,
                    Roles = u.UserName.GetRoles()
                }
                : null;
        })
            .Where(u => u != null)
            .ToList();
Run Code Online (Sandbox Code Playgroud)

想知道是否有办法结合使用SELECTWHERE子句.

我试过了:

        model.Users = users
            .Select(u =>
            {
                var membershipUser = Membership.GetUser(u.UserName);
                if (membershipUser != null)
                    return new UserBriefModel
                    {
                        Username = u.UserName,
                        Fullname = u.FullName,
                        Email = membershipUser.Email,
                        Roles = u.UserName.GetRoles()
                    };
            })
            .ToList();
Run Code Online (Sandbox Code Playgroud)

但智能感知提示语法错误.这迫使我添加一个return null声明:

        model.Users = users
            .Select(u =>
            {
                var membershipUser = Membership.GetUser(u.UserName);
                if (membershipUser != null)
                    return new UserBriefModel
                    {
                        Username = u.UserName,
                        Fullname = u.FullName,
                        Email = membershipUser.Email,
                        Roles = u.UserName.GetRoles()
                    };
                return null;
            })
            .ToList();
Run Code Online (Sandbox Code Playgroud)

那么编写这个SELECT语句的正确方法是什么,所以只有有效的记录被选入我的模型?

Ser*_*rvy 7

从概念上讲,您实际上有三个操作:

  1. 将用户名投影到成员资格用户
  2. 过滤掉空会员用户
  3. 将成员用户投射到模型

就是你的查询应该如何看待.你的第一个查询已经尝试将第1步和第3步结合在一起,但是你正在努力,因为第二步确实应该在两者的中间,而你需要跳过的那些箍不是很漂亮.

当您单独表示所有三个操作时,查询实际上变得更简单和可读(并成为惯用的LINQ代码).

model.Users = users
    .Select(user => new
    {
        user,
        membershipUser = Membership.GetUser(user.UserName)
    })
    .Where(pair => pair.membershipUser != null)
    .Select(pair => new UserBriefModel
    {
        Username = pair.user.UserName,
        Fullname = pair.user.FullName,
        Email = pair.membershipUser.Email,
        Roles = pair.user.UserName.GetRoles()
    })
    .ToList();
Run Code Online (Sandbox Code Playgroud)

这是一个查询,也可以在查询语法中更有效地编写:

model.Users = from user in users
                let membershipUser = Membership.GetUser(user.UserName)
                where membershipUser != null
                select new UserBriefModel
                {
                    Username = user.UserName,
                    Fullname = user.FullName,
                    Email = membershipUser.Email,
                    Roles = user.UserName.GetRoles()
                };
Run Code Online (Sandbox Code Playgroud)

至于你是否可以将过滤投射结合到单个LINQ操作中的字面问题,它肯定是可能的.这对问题来说是一个不合适的解决方案,但使用它SelectMany可以让你同时过滤和投影.这可以通过将项目投影到包含要将其投影到的值的一个项目序列或基于谓词的空序列来完成.

model.Users = users
    .SelectMany(u =>
    {
        var membershipUser = Membership.GetUser(u.UserName);
        return membershipUser != null
            ? new[]{ new UserBriefModel
            {
                Username = u.UserName,
                Fullname = u.FullName,
                Email = membershipUser.Email,
                Roles = u.UserName.GetRoles()
            }}
            : Enumerable.Empty<UserBriefModel>();
    }).ToList();
Run Code Online (Sandbox Code Playgroud)

当然,每次使用此代码时,都会杀死一只小猫.不要杀小猫; 请改用之前的查询.

  • @LIUFA嗯,我甚至没有看到你的帖子,直到你提到它,并且没有投票,所以我只能猜测,但有些事情脱颖而出.首先,您在第一次发布时有一个非常明显不同的答案,并在以后编辑.我不确定投票何时进入,但它们可能是基于您的第一次修订.接下来,更重要的是,你的答案不能解释任何事情.只是发布一些代码而不解释你已经改变了什么,以及你改变它的原因,从根本上影响了帖子的价值.最后,我的答案*中的代码与您的代码不同,尽管类似. (2认同)