我知道我的问题有点混乱,因为我还没有找到一个更好的方式来问它,但我相信这不是一个很难解决的问题。
事情是这样的:
我应该在实体存储库中名为GetAllPlaces
的方法中返回一个List<Place>
。
地点实体:
public Guid PlaceId { get; set; }
public string Name { get; set; }
public List<Hour> Hours { get; set; }
小时实体:
public Guid HourId { get; set; }
public Guid DayOfTheWeekId { get; set; }
public DayOfTheWeek DayOfTheWeek { get; set; }
public DateTime OpenHour { get; set; }
public DateTime CloseHour { get; set; }
public Guid PlaceId { get; set; }
public Place Place { get; set; }
每个Place
都有一个List<Hour>
属性,我尝试过滤这个小时列表,不返回对这个方法的调用者关闭的地点,到目前为止,我只过滤了这个地点所在时区的今天的小时:
public async Task<IReadOnlyList<Place>>
GetAllPlacesAsync()
{
var places = await context.Places
.AsNoTracking()
.Include(s => s.Hours
// here I'm filtering to get just today's Hour like explained previously
.Where(d => d.DayOfTheWeek.DayName
== TimeZoneInfo
.ConvertTime(DateTime.Now,
TimeZoneInfo
.FindSystemTimeZoneById(d.Place.Timezone.Name))
.DayOfWeek
.ToString()).FirstOrDefault())
// a second .Where() would filter on the .Include()
// or on the "places" List but not on its Hours.
// How to further filter to do something like this:
// if Place.Hour.Open <= timeNowInPlaceTimezone
// && Place.Hour.Close >= timeNowInPlaceTimezone ? passToList : dontPassToList
.Distinct()
.ToListAsync();
return places;
}
你知道我如何过滤它,只得到地方的Hour
是在开放和关闭时间之间的今天在其时区的地方?
2条答案
按热度按时间c9qzyr3d1#
首先澄清一下我的理解或您的数据:每个地点都有一个
List<Hour>
集合,其中每个Hour
对象都有属性DayOfTheWeek
、Open
和Close
-类似于store hours sign上的行项目。此外,每个place
都有一个关联的时区,在检查place.Hours
集合之前,需要将当前(UTC)日期/时间转换为该时区。我不认为
.Include()
是您在这里想要的,因为该函数是用于选择额外的数据,以便与结果一起加载,而不是用于过滤结果。我的期望是您想要类似
.Where(place => place.Hours.Any(hour => hours-matches-local-time)
的东西。但是,
hours-matches-local-time
部分可能包含复杂的计算,可能不必要地在.Any()
内部对同一位置进行多次评估。为避免冗余计算,外部.Where()
中的条件可被制成代码块,其中本地星期几和本地时间在每个位置计算一次,并被分配给变量,然后在内部.Any()
内重复引用。尝试以下内容:
以上使用 LINQ Method syntax。另一种方法是使用 LINQ Query syntax,它也可以使用
let
子句计算局部变量。This post提供了演示其中一些技术的答案。(也许在LINQ查询语法方面比我更有经验的人可以发布翻译。)可能还有其他改进的机会,例如按时区对地点分组,并对每个组计算一次当地日期/时间。最终将使用
.SelectMany()
来处理每个组并使结果变平。结果可能如下所示:y4ekin9u2#
不确定您的开放/关闭时间条件,但查询应如下所示: