Che*_*hev 5 c# linq lambda linq-to-entities expression
我有一个表达式,我在几个LINQ查询中使用了几次,所以我把它分成了它自己的返回表达式的方法.函数的lambda部分看起来很乱.任何人都想破解重构并使其更具可读性和/或更小?
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);
}
Run Code Online (Sandbox Code Playgroud)
它正在做的快速英文描述是检查布尔值sent并检查Message.FromUser或Message.ToUser基于该布尔值.
如果用户正在查看他/她的发件箱,sent则为真,并且会看到是否x.FromUser.Username == username和x.SenderDeleted == false.
如果用户正在查看他/她的收件箱,那么它会执行相同的逻辑,但是发送是错误的,而是检查x.ToUser而x.RecipientDeleted不是.
也许这是最简单的方法,但我对一些重构持开放态度.
我真的很喜欢Davy8的答案,但我决定更进一步,用一个嵌套函数做两个表达式而不是一个表达式.现在我有以下方法:
/// <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;
}
Run Code Online (Sandbox Code Playgroud)
所以现在我的查询看起来像这样:
/// <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;
}
Run Code Online (Sandbox Code Playgroud)
我会说那些是非常英文可读的查询,谢谢你们!
参考:http://www.codetunnel.com/blog/post/64/how-to-simplify-complex-linq-expressions
将其拆分为一个单独的函数:
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;
}
Run Code Online (Sandbox Code Playgroud)
或者也可以内联它以维持闭包的使用:
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);
}
Run Code Online (Sandbox Code Playgroud)
(编辑后用于string.Equals具有StringComparison.InvariantCultureIgnoreCase不同文化设置的奇怪边缘情况。)
| 归档时间: |
|
| 查看次数: |
234 次 |
| 最近记录: |