#c# #linq
#c# #linq
Вопрос:
У меня проблема, которую я не уверен в лучшем способе решения. И мои «решения» приводят к очень сложному коду.
Пример: в моей модели данных есть диваны и яблоки. И класс Sofa, и класс Apple имеют свойство isFavorite и дату FavoriteChange. У меня есть сервис, который я использую следующим образом:
List<Apple> top25FavApples = _appleService.FindFavorites(25);
List<Sofa> top25FavSofas = _sofaService.FindFavorites(25);
Теперь, когда у меня есть избранные яблоки и диваны, мне нужно объединить коллекции, упорядочить по FavoriteChangeDate, а затем ограничить до 25 лучших. Вот тут я и застрял.
Возможное решение: создайте промежуточный класс для хранения Apple / Sofa и FavoriteDate. Выполните выборки для коллекции промежуточных объектов, а затем запустите другой запрос, чтобы вернуть яблоки и диваны самостоятельно.
Комментарии:
1. Вы можете заставить Apple и Sofa наследовать
IFavoratable
интерфейс.
Ответ №1:
Лучшим решением было бы создать IFavoriteable
интерфейс, который определяет FavoriteChangeDate
свойство, и заставить два класса реализовать его. Затем вы можете просто выполнить приведение IFavoriteable
и выполнить Linq OrderBy
для него.
class Program
{
static void Main()
{
List<Apple> top25FavApples = _appleService.FindFavorites(25);
List<Sofa> top25FavSofas = _sofaService.FindFavorites(25);
List<IFavoriteable> top25Total = top25FavApples.Concat<IFavoriteable>(top25FavSofas)
.OrderBy(x => x.FavoriteChangeDate)
.Take(25).ToList();
}
}
public interface IFavoriteable
{
DateTime? FavoriteChangeDate { get; }
}
public class Apple : IFavoriteable
{
public DateTime? FavoriteChangeDate { get; set; }
//...
}
public class Sofa : IFavoriteable
{
public DateTime? FavoriteChangeDate { get; set; }
//...
}
Ответ №2:
Если вы не можете добавить какой-либо интерфейс или базовый класс (что было бы лучше), одним из вариантов может быть приведение к динамическому и запрос в динамическом режиме, например:
top25FavApples.Cast<dynamic>()
.Concat(top25Sofas.Cast<dynamic>())
.OrderBy(x => (DateTime)x.FavoriteChangeDate).Take(25)