我怎么可能收拾这个拉姆达? [英] How might I clean up this lambda?

查看:120
本文介绍了我怎么可能收拾这个拉姆达?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有几个LINQ使用了几次的表达式查询,所以我分离出来到它自己的方法,它返回的表达。该函数的拉姆达部分是那种凌乱看。 ?谁都希望采取裂缝在重构它,使得它更具可读性和/或较小

I have an expression that I use a few times in several LINQ queries so I separated it out into it's own method that returns the expression. The lambda portion of the function is kind of messy looking. Anyone want to take a crack at refactoring it and making it more readable and/or smaller?

    private Expression<Func<Message, bool>> UserSelector(string username, bool sent)
    {
        return x => ((sent ? x.FromUser : x.ToUser).Username.ToLower() == username.ToLower()) && (sent ? !x.SenderDeleted : !x.RecipientDeleted);
    }

的它在做什么是它正在检查布尔<快速英文说明code>发送和检查无论是 Message.FromUser Message.ToUser 基于布尔值。

A quick English description of what it's doing is it is checking the boolean sent and checking either the Message.FromUser or the Message.ToUser based on that boolean.

如果用户在看他/她的发件箱,发送是真实的,它会看看 x.FromUser.Username ==用户名 x.SenderDeleted ==虚假

If the user is looking at his/her outbox, sent is true and it will see if x.FromUser.Username == username and x.SenderDeleted == false.

如果用户在看他/她的收件箱中,然后它不相同的逻辑,但送是假的,它会检查 x.ToUser x.RecipientDeleted 代替。

If the user is looking at his/her inbox then it does the same logic, but sent is false and it checks x.ToUser and x.RecipientDeleted instead.

也许这是最简单的方式,但我愿意接受一些重构。

Maybe this is the easiest way but I'm open to some refactoring.

我真的很喜欢Davy8的答案,但我决定采取更进一步,做两个表达式,而不是一个表达一个嵌套函数。现在,我有以下几种方法:

I really liked Davy8's answer but I decided to take a step further and do two expressions instead of one expression with a nested function. Now I have the following methods:

    /// <summary>
    /// Expression to determine if a message belongs to a user.
    /// </summary>
    /// <param name="username">The name of the user.</param>
    /// <param name="sent">True if retrieving sent messages.</param>
    /// <returns>An expression to be used in a LINQ query.</returns>
    private Expression<Func<Message, bool>> MessageBelongsToUser(string username, bool sent)
    {
        return x => (sent ? x.FromUser : x.ToUser).Username.Equals(username, StringComparison.OrdinalIgnoreCase);
    }

    /// <summary>
    /// Expression to determine if a message has been deleted by the user.
    /// </summary>
    /// <param name="username">The name of the user.</param>
    /// <param name="sent">True if retrieving sent messages.</param>
    /// <returns>An expression to be used in a LINQ query.</returns>
    private Expression<Func<Message, bool>> UserDidNotDeleteMessage(string username, bool sent)
    {
        return x => sent ? !x.SenderDeleted : !x.RecipientDeleted;
    }



所以,现在我的疑问是这样的:

So now my queries look like this:

    /// <summary>
    /// Retrieves a list of messages from the data context for a user.
    /// </summary>
    /// <param name="username">The name of the user.</param>
    /// <param name="page">The page number.</param>
    /// <param name="itemsPerPage">The number of items to display per page.</param>
    /// <param name="sent">True if retrieving sent messages.</param>
    /// <returns>An enumerable list of messages.</returns>
    public IEnumerable<Message> GetMessagesBy_Username(string username, int page, int itemsPerPage, bool sent)
    {
        var query = _dataContext.Messages
            .Where(MessageBelongsToUser(username, sent))
            .Where(UserDidNotDeleteMessage(username, sent))
            .OrderByDescending(x => x.SentDate)
            .Skip(itemsPerPage * (page - 1))
            .Take(itemsPerPage);
        return query;
    }

    /// <summary>
    /// Retrieves the total number of messages for the user.
    /// </summary>
    /// <param name="username">The name of the user.</param>
    /// <param name="sent">True if retrieving the number of messages sent.</param>
    /// <returns>The total number of messages.</returns>
    public int GetMessageCountBy_Username(string username, bool sent)
    {
        var query = _dataContext.Messages
            .Where(MessageBelongsToUser(username, sent))
            .Where(UserDidNotDeleteMessage(username, sent))
            .Count();
        return query;
    }



我会说这些都是一些非常英语阅读查询,谢谢你们!

I would say those are some very English readable queries, thanks guys!

参考:的 http://www.codetunnel.com/blog/post/64/how-to-simplify-complex-linq-expressions

推荐答案

拆分出来成为一个单独的函数:

Split it out into a separate function:

    private Expression<Func<Message, bool>> UserSelector(string username, bool sent)
    {
        return message=> InnerFunc(message, username, sent);
    }

    private static bool InnerFunc(Message message, string username, bool sent)
    {
        if(sent)
        {
            return string.Equals(message.FromUser.Username, username, StringComparison.InvariantCultureIgnoreCase) && !message.SenderDeleted;
        }
        return string.Equals(message.ToUser.Username, username, StringComparison.InvariantCultureIgnoreCase) && !message.RecipientDeleted;
    }

或者或者也可以内联保持闭合用法:

Or alternatively it can be inlined to maintain closure usage:

    private Expression<Func<Message, bool>> UserSelector(string username, bool sent)
    {
        Func<Message, bool> innerFunc = message =>
        {
            if (sent)
            {
                return string.Equals(message.FromUser.Username, username, StringComparison.InvariantCultureIgnoreCase) &&
                        !message.SenderDeleted;
            }
            return string.Equals(message.ToUser.Username, username, StringComparison.InvariantCultureIgnoreCase) &&
                    !message.RecipientDeleted;
        };
        return message => innerFunc(message);
    }



(编辑使用 string.Equals StringComparison.InvariantCultureIgnoreCase 奇数边缘情况与不同的文化设置。)

(Edited to use string.Equals with StringComparison.InvariantCultureIgnoreCase for odd edge cases with different culture settings.)

这篇关于我怎么可能收拾这个拉姆达?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆