使用虚拟(外键)引用通过延迟/急切加载提高效率

时间:2017-08-03 22:38:20

标签: c# linq lambda

我对Lambda / Linq比较陌生,但是我想从特定日历中检索所有事件,但事件仍在将来......

如果我使用:

EventCalendar eventCalendar;
eventCalendar = db.Events_Calendars.Find(id);

我可以通过视图中的当前日期获取所有事件并进行过滤,但我认为这不是最好的方法。

模型如下:

[Table("Events_Calendars")]
public class EventCalendar
{
    public int Id { get; set; }
    public string Calendar { get; set; }
    public virtual List<Event> Events { get; set; }
}

事件模型是:

public class Event
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string Description { get; set; }
    public DateTime Start { get; set; }
    public DateTime End { get; set; }
    public int? Capacity { get; set; }
    .
    .
    .
}

视图是:

@model WebApps.Areas.Events.Models.EventCalendar
@* does some stuff with the EventCalendar *@

@Html.Partial("_Events", Model.Events.ToList())

_Events partial view:

@model IEnumerable<WebApps.Areas.Events.Models.Event>
.        
. 
. 
@foreach (var item in Model)
    {
        if (item.End > DateTime.Today)
        {
            @* Do that thing *@
        }    
    }

上面的示例有效,但是在视图中放置逻辑流程。我想从视图中删除过滤器逻辑,并使查询完成所有工作。

如果日历中至少有一个由于相同的where子句条件而导致的未来事件,则以下内容仅为我提供日历。我把它留作了我需要过滤的参考,但它仍然会返回过去和未来的所有事件:

eventCalendar = db.Events_Calendars
        .Where(x => x.Events.Any(y => y.End >= DateTime.Today) && x.Id == id)
        .FirstOrDefault();

当我要求日历并且仍然只使用一个语句时,有没有办法可以过滤事件?

注意:此系统默认加载默认为打开。

编辑澄清=返回“不超过1个日历以及所有相关的未来事件”;

1 个答案:

答案 0 :(得分:1)

<?php if(isset($_GET["number"]) && isset($_GET["age"])) { $number = htmlspecialchars($_GET["number"]); $age = htmlspecialchars($_GET["age"]); function Math ($number, $age) { $result = $number + $age; return $result; } echo Math($number, $age); } ?> 将过滤至少有一个Events.Any事件的Events_Calendars。它不会过滤Events_Calendar.Events本身。

以下内容仅返回匹配的Events_Calendar的End >= DateTime.Today

Events.End >= DateTime.Today

如果您向Events添加Events_Calendar属性,您仍然可以显示日历。

或者,您可以重新映射Events_Calendar,例如使用工厂方法:

var events = db.Events_Calendars
    .Where(x => x.Id == id)
    .SelectMany(x => x.Events)
    .Where(x => x.End >= DateTime.Today);

请注意,代码示例表示新的Events_Calendar具有事件的参考副本。

另一种可能性是Events_Calendar

上的一种方便性方法
var newCal = Events_Calendars.WithFutureEvents(db.Events_Calendars.Find(id))

class Events_Calendar
{
    public static Events_Calendar WithFutureEvents(Events_Calendar cal)
    {
        return new Events_Calendar()
        {
            Id = cal.Id,
            Calendar = cal.Calendar,
            Events = cal.Events.Where(x => x.End >= DateTime.Today).ToList()
        };
    }
}