[英]LINQ where list within a list contains a value
早上好。 我對使用 LINQ 還是很陌生,我已經嘗試了所有我能想到的組合但都沒有成功,我有一個日歷 object 和 object。 CalendarDays 列表。 顯然,我要做的是檢索特定的日期或日期范圍。 我想要日歷值以及 CalendarDay 列表的元素,我嘗試了許多不同的組合。 但他們告訴我我不能將我的 CalendarDay 轉換為 bool 類型,這是我試過的一個例子,但我只得到 CalendarDay。 不是日歷? 不可能同時獲得這兩個值嗎?
var row = calendar.SelectMany(c => c.Days)
.Where(d => d.Date == request.Date);
這是我的日歷 class:
public class Calendar : ICalendar<string>
{
private List<CalendarDay> _calendarDays;
public Calendar()
{
_calendarDays = new List<CalendarDay>();
}
public string Id { get; set; }
public int Year { get; set; }
public List<CalendarDay> Days { get => _calendarDays; }
public void AddCalendarDay(int quarter, string season, int period, int weekOfPeriod, int weekOfYear, int dayOfYear, string date)
{
var existingDay = _calendarDays.SingleOrDefault(x => x.Date == date);
if (existingDay == null)
{
_calendarDays.Add(new CalendarDay
{
Quarter = quarter,
Season = season,
Period = period,
WeekOfPeriod = weekOfPeriod,
WeekOfYear = weekOfYear,
DayOfYear = dayOfYear,
Date = date
});
}
else
{
existingDay.Quarter = quarter;
existingDay.Season = season;
existingDay.Period = period;
existingDay.WeekOfPeriod = weekOfPeriod;
existingDay.WeekOfYear = weekOfYear;
existingDay.DayOfYear = dayOfYear;
existingDay.Date = date;
}
}
}
我忘了提到這是 API 的 GET 方法,此檢索位於 GetByDate 處理程序中。 正如您在下面看到的,GetItemsAsync 的結果被填充到一個列表中。 在那之后,我想提取單個日期並將其傳遞給映射器。 希望這有助於澄清我在尋找什么!
public async Task<CalendarDto> HandleAsync(GetCalendarByDateQuery request)
{
var spec = new CalendarByYearSpecification(request.Year);
var result = await _masterRepository.GetItemsAsync(spec);
var calendar = result.Results.ToList();
// retrieval of the specific date goes here
var dto = _mapper.Map<Calendar, CalendarDto>(calendar.FirstOrDefault());
return dto;
}
謝謝!
也許最好的做法是在日歷 class 中創建一個新方法,用於過濾您的日期並返回一個新的日歷 object,其中僅包含所選日期
public class Calendar : ICalendar<string>
{
private List<CalendarDay> _calendarDays;
public Calendar()
{
_calendarDays = new List<CalendarDay>();
}
public Calendar FilterByDate(CalendarDay requestedDate)
{
Calendar result = new Calendar();
// These lines could be a lot more complex if you have many
// properties to duplicate. As it stands now this will suffice,
// but in more complex cases you could look at some form of
// serialization and deserialization
result.Id = this.Id;
result.Year = this.Year;
result.Days = this.Days.Where(x => x.Date == requestedDate.Date).ToList();
return result;
}
現在您需要從日歷 class 的內部代碼訪問 Days 屬性,以便能夠使用 Where 的結果進行設置
public List<CalendarDay> Days { get => _calendarDays; internal set {_calendarDays = value;}}
這將允許您以這種方式調用該方法
Calendar filtered = currentCalendar.FilterByDate(aCalendarDayInstance);
聽起來您的日歷 object 已經有了,因此您已經可以使用這些值。 然后,如果您想獲得一個特定的日歷日,那么您可以使用FirstOrDefault
獲得它(假設您希望它返回null
如果它不存在):
var calendarDay = calendar.Days.FirstOrDefault(d => d.Date == request.Date);
如果你想要一個日期范圍,那么你可以使用Where
方法。
var calendarDays = calendar.Days.Where(d => d.Date > request.StartDate && d.Date < request.EndDate).ToList();
希望這可以幫助
這是使用 .Select() 和匿名類型的方法。 首先,您在日歷集合上運行 select 語句,並獲得一個匿名類型,其中包含對日歷的引用以及與您的過濾器匹配的日期集合。 然后你 select 只有 Days.Count 大於零的對象:
var rows = calendar.Select(c => new { Calendar = c,
Days = c.Days.Where(d => d.Date == request.Date).ToList() })
.Where(cd => cd.Days.Count() > 0)
.ToList();
foreach (var row in rows)
{
var cal = row.Calendar;
foreach (var day in row.Days)
{
var dayDate = day.Date;
}
}
以下是您的代碼的修改版本,其中包含一組使其工作的修復:
using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
interface ICalendar<T> : IEnumerable<T>
{
}
public class CalendarDay
{
public int Quarter {get;set;}
public string Season {get;set;}
public int Period {get;set;}
public int WeekOfPeriod {get;set;}
public int WeekOfYear {get;set;}
public int DayOfYear {get;set;}
public string Date {get;set;}
}
public class Calendar : ICalendar<CalendarDay>
{
private List<CalendarDay> _calendarDays;
public Calendar()
{
_calendarDays = new List<CalendarDay>();
}
public string Id { get; set; }
public int Year { get; set; }
public List<CalendarDay> Days { get => _calendarDays; }
IEnumerator IEnumerable.GetEnumerator()
{
return _calendarDays.Select(x => x).GetEnumerator();
}
public IEnumerator<CalendarDay> GetEnumerator()
{
return _calendarDays.Select(x => x).GetEnumerator();
}
public void AddCalendarDay(int quarter, string season, int period, int weekOfPeriod, int weekOfYear, int dayOfYear, string date)
{
var existingDay = _calendarDays.SingleOrDefault(x => x.Date == date);
if (existingDay == null)
{
_calendarDays.Add(new CalendarDay
{
Quarter = quarter,
Season = season,
Period = period,
WeekOfPeriod = weekOfPeriod,
WeekOfYear = weekOfYear,
DayOfYear = dayOfYear,
Date = date
});
}
else
{
existingDay.Quarter = quarter;
existingDay.Season = season;
existingDay.Period = period;
existingDay.WeekOfPeriod = weekOfPeriod;
existingDay.WeekOfYear = weekOfYear;
existingDay.DayOfYear = dayOfYear;
existingDay.Date = date;
}
}
}
public class Test
{
public static void Main(string[] args)
{
var cal = new Calendar();
var row = cal.Select(c => c.Date).Where(d => d == "Fill Date for Comparison");
}
}
重要修改:
ICalendar<T>
實現IEnumerable<T>
,以確保 Linq 調用有效IEnumerable<T>
直到並且除非ICalendar<T>
實現了某些特殊功能GetEnumerator()
方法來編譯代碼Test
中,我們撥打電話, Select
結果為IEnumerable<CalendarDay>
,其中Where
用於獲取Date
並與請求日期進行比較其他要點
您應提供簡單/可編譯的代碼,並且只關注主要問題陳述,在這里我必須努力使您的代碼編譯。
SelectMany
是Collection flattening, Select
是簡單的Collection 選擇,您需要提供直接在其上工作的代碼,無需任何額外要求
所有 Linq 方法都是擴展方法,您應該從.Net 參考源代碼中查看它們的定義,這將有助於更好地使用代碼
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.