Asp.net mvc Linq-包含和筛选-嵌套集合

Asp.net mvc Linq-包含和筛选-嵌套集合,asp.net-mvc,entity-framework,linq,Asp.net Mvc,Entity Framework,Linq,我正在开发一个mvc应用程序,人们可以在其中搜索火车路线。我首先使用实体框架编写了数据库代码,但我似乎不知道如何询问更复杂的查询 我有一组在viewmodel中使用的管线。因此,第一步是询问哪些路线有特定的起点和终点站。然后我想包括一个时间表,其中某一天设置为true,并且该时间表的开始和结束日期匹配。这与我使用此表的行程集合相链接,因为路线一天运行多次。从这里,我可以找到所有与表RouteAsstations对应的到达和离开时间的车站 所以我在想: public IEnumerable<

我正在开发一个mvc应用程序,人们可以在其中搜索火车路线。我首先使用实体框架编写了数据库代码,但我似乎不知道如何询问更复杂的查询

我有一组在viewmodel中使用的管线。因此,第一步是询问哪些路线有特定的起点和终点站。然后我想包括一个时间表,其中某一天设置为true,并且该时间表的开始和结束日期匹配。这与我使用此表的行程集合相链接,因为路线一天运行多次。从这里,我可以找到所有与表RouteAsstations对应的到达和离开时间的车站

所以我在想:

public IEnumerable<Route> Search(DateTime date, int? departure, int? arrival)
{
   var day = date.DayOfWeek.ToString();
   return db.Routes.Where(r => r.DepartureStationID == departure && r.ArrivalStationID == arrival)
                   .Include(s => s.Train)
                   //using linq.dynamic here 
                   .Include(r => r.Schedule.where(day + "==" + true)
                   .Include(sch => sch.trip.where(date > sch.DepartureTime)
                   .Include(route => route.RouteHaseStations)
                   .Include(st => st.Stations)
}
但这当然不起作用。以下是我的模型:

public class Route
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int RouteID { get; set; }
    public String RouteName { get; set; }
    [ForeignKey("Train")]
    public int TrainID { get; set; }
    [ForeignKey("Station")]
    public int DepartureStationID { get; set; }
    [ForeignKey("Station")]
    public int ArrivalStationID { get; set; }
    public virtual ICollection<Schedule> Schedule { get; set; }
    public virtual Train Train { get; set; }
    public virtual Station DepartureStation { get; set; }
    public virtual Station ArrivalStation { get; set; }
}

public class Station
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public  int StationID { get; set; }
    [Display(Name = "Station")]
    public  String Name { get; set; }
    public int  Platforms { get; set; }
    public float Latitude { get; set; }
    public float Longitude { get; set; }
    public virtual ICollection<RouteHasStation> RouteHasStation { get; set; }
}

public class Train
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public  int TrainID { get; set; }
    public  String Name { get; set; }
    public virtual ICollection<Route> Route { get; set; }
}

public class Schedule
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int ScheduleID { get; set; }
    [ForeignKey("Route")]
    public int RouteID { get; set; }
    public Boolean Monday { get; set; }
    public Boolean Tuesday { get; set; }
    public Boolean Wednesday { get; set; }
    public Boolean Thursday { get; set; }
    public Boolean Friday { get; set; }
    public Boolean Saturday { get; set; }
    public Boolean Sunday { get; set; }
    public DateTime? StartDate { get; set; }
    public DateTime? EndDate { get; set; }
    public virtual ICollection<Trip> Trip { get; set; }
    public virtual Route Route { get; set; }
}

public class Trip
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int TripID { get; set; }
    [ForeignKey("Schedule")]
    public int ScheduleID { get; set; }
    public DateTime DepartureTime { get; set; }
    public virtual ICollection<RouteHasStation> RouteHasStation { get; set; }
}

public class RouteHasStation
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int RouteHasStationID { get; set; }
    [ForeignKey("Station")]
    public int StationID { get; set; }
    public virtual Station Station { get; set; }
    [ForeignKey("Trip")]
    public int TripID { get; set; }
    public virtual Trip Trip { get; set; }
    [DataType(DataType.Time)]
    [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:HH:mm}")]
    public DateTime? Arrival { get; set; }
    [DataType(DataType.Time)]
    [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:HH:mm}")]
    public  DateTime? Departure { get; set; }
    public int Platform { get; set; }
    public float Distance { get; set; }
}

除了键入错误之外,您的程序还有几个问题

声明

.Include(r => r.Schedule.where(day + "==" + true)
没有正确的谓词。即使您能够将其更改为谓词,linqtosql也不知道如何将其作为查询处理,因为您需要根据变量day从Schedule类调用不同的过程

由于包含的组合,我不确定您想要什么。根据您的描述,我想说您希望在给定的搜索日期运行具有特定出发站和到达站的所有路线

我不确定您是在使用现有数据库,还是仍在开发它。在后一种情况下,考虑更改调度类,使调度是一个标记的枚举,如

[Flags]
public enum MyDayOfWeek
{
    Sunday = 1 << System.DayOfWeek.Sunday,         // 0x01
    Monday = 1 << System.DayOfWeek.Monday,         // 0x02
    Tuesday = 1 << System.DayOfWeek.Tuesday,       // 0x04
    Wednesday 1 << System.DayOfWeek.Wednesday,     // 0x08
    Thursday 1<< System.DayOfWeek.Thursday,        // 0x10
    Friday = 1 << System.DayOfWeek.Friday,         // 0x20
    Saturday = 1 << System.DayOfWeek.Saturday,     // 0x40
}

public class Schedule
{
    public int ScheduleID { get; set; }
    public int RouteID { get; set; }
    public MyDayOfWeek RunDays { get; set; }
    public virtual ICollection<Trip> Trips {get; set;}
    ...
获取计划在给定日期时间运行的所有路由的查询如下:

System.DayOfWeek dayOfWeek = day.DayOfWeek;
MyDayOfWeek myDayOfWeek = (MyDayOfWeek)( 1 << (int)dayOfWeek);

var routesRunningOnDate = db
    .Where(route => route.DepartureStation etc
        && (route.RunDays & myDayOfWeek) == myDayOfWeek)
用法:

db.Routes.AsEnumerable().Where (route => route.Schedule.IsScheduled(date));
此外,您似乎没有正确地将所有包含项括起来。你所有的参数r,s,sch,route,st都应该是routes,而实际上你的sch应该是Schedules,等等

请注意,只要不真正枚举序列,也不处理DbContext,就不需要Include语句。当您没有特别要求一个值,但希望它们位于本地内存中时,需要Include语句

如果您有一个iQueryTable,它不使用表中的某个字段,并且稍后使用此字段,则在枚举它之前,该字段会自动添加到查询中,从而添加到SQL查询中:

var query1 = routes.Where(r.DepartureStationID == departure && r.ArrivalStationID == arrival);
var query2 = query1.Where(route => route.Schedule.Trips...)
如果没有额外的include,linqtosql知道需要与Schedule表进行连接

我想您需要以下路线:

1从出发站到到达站的所有路线 计划在第二天运行的 3和那之后都安排不上了?行程表。出发时间 4确保您拥有route.RouteHasStations的所有站点

不确定Schedule.DepartureTime是否表示此计划有效的第一天,因此ActivationDate不是更好的名称吗?或者发车时间是否为列车在预定日期发车的时间

在后一种情况下,声明

.Include(sch => sch.trip.where(date > sch.DepartureTime)
不执行您想要的操作:它返回所有在日期之后的日期安排的计划,即使出发时间晚于日期中的时间

db.Routes.Where(route => route.DepartureStaionId == departure
    && route.ArrivalStationId == arrival
    && route.Schedule.IsScheduled(date)
    && date > route.Trips.DepartureTime)
    // you don't need to include Schedule and Trips explicitly
    // unless you need their fields outside this query

    .Include(route => route.Train)
    .Include(route => route.HasTrips)
    // only include these if you need their fields outside this query
    // if the only thing from train you want is Train.Name,
    // use route.Train.Name in a select after the Where

请显示错误。在StackOverflow中,有关筛选包含的问题很多。欢迎使用Stack OverFlow。请参阅中的一些示例问题,以便您了解如何正确提问,以便其他用户快速回答问题:Good LuckI一直在浏览allot的主题,但没有多少是关于儿童的孩子和保持原始模型的过滤器。
.Include(sch => sch.trip.where(date > sch.DepartureTime)
db.Routes.Where(route => route.DepartureStaionId == departure
    && route.ArrivalStationId == arrival
    && route.Schedule.IsScheduled(date)
    && date > route.Trips.DepartureTime)
    // you don't need to include Schedule and Trips explicitly
    // unless you need their fields outside this query

    .Include(route => route.Train)
    .Include(route => route.HasTrips)
    // only include these if you need their fields outside this query
    // if the only thing from train you want is Train.Name,
    // use route.Train.Name in a select after the Where