У меня есть выражение, которое я использую несколько раз в нескольких запросах LINQ, поэтому я разделил его на собственный метод, который возвращает выражение.Лямбда-часть функции выглядит беспорядочно.Кто-нибудь хочет попробовать его рефакторинг и сделать его более читабельным и / или меньшим?
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);
}
Краткое описание того, что он делает, это проверка логического sent
и проверка либо Message.FromUser
или Message.ToUser
на основе этого логического значения.
Если пользователь смотрит на свой почтовый ящик, sent
имеет значение true, и он увидит, если 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;
}
Так что теперь мои запросы выглядят так:
/// <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;
}
Я бы сказал, что это очень удобочитаемые запросы на английском языке, спасибо, ребята!
Ссылка: http://www.codetunnel.com/blog/post/64/how-to-simplify-complex-linq-expressions