开发者

How can i simplify this LINQ-To-Entity query, and make it dynamic

I have this query for getting data through Entity Framework, which works today. Thing is, i want to create the query dynamically, i.e build it up in blocks, but i can't figure out how exactly to do it. I believe if i can somehow save one of the values that i retrieve in the beginning i can do it, but now i retrieve it twice (probably a bit slow as well? Unless the compiler fixes it before quering). Makes sense? Here is the LINQ:

from d in db.trains
where d.cancelled
&& d.station == toStation
&& d.date >= fromDate.Date
&& d.date <= toDate.Date
&& (from k in db.trains
    where 
    k.date == d.date
    && k.trainId == d.trainId
    && k.stationId == fromStation
    && k.position <= d.position
    select k.trainId).Contains(d.trainId)开发者_开发知识库
select new
{
  trainId = d.trainId,
  date = d.date,
  arrival = d.arrival,
  departure = (from k in db.trains
               where
               k.date == d.date
               && k.trainId == d.trainId
               && k.stationId == fromStation
               && k.position <= d.position
               select k.departure).FirstOrDefault()
}
);

So you see, in order to get the departure, i have to retrieve the same thing again. So what i'm asking is can i save the object in the first query and then retrieve it later somehow? I can't get the syntax working.

The database looks something like this:

trainId stationId date       arrival departure position

1       99        2010-10-11 10:00   10:10     1
1       98        2010-10-11 11:20   11:30     2
1       47        2010-10-11 12:30   12:40     3
2       99        2010-10-10 15:00   15:10     5

etc

So bascially, i need to retrieve two objects from the db, where the first one has stationId x and the other one has stationId y and both have the same date and trainId, and they have to be in the proper order, based on position (trains go both ways, but with different trainId's).

Also, i would like to do be able to build this query dynamically, like this:

var trains = from d in db.trains
             select d;

if (id > 0)
  trains = trains.Where(p => p.trainId == id);

if (date != DateTime.MinValue)
  trains = trains.Where(p => p.date == date);

var items = (from train in trains).ToList();

I.e based on if various variables have values.


You can use the let statement to store local variables and reuse them later
Something like this:

from d in db.trains
where d.cancelled
&& d.station == toStation
&& d.date >= fromDate.Date
&& d.date <= toDate.Date
let departures = (from k in db.trains
    where 
    k.date == d.date
    && k.trainId == d.trainId
    && k.stationId == fromStation
    && k.position <= d.position
    select k)
where departures.Select(d => d.trainId).Contains(d.trainId)
select new
{
  trainId = d.trainId,
  date = d.date,
  arrival = d.arrival,
  departure = departures.Select(d => d.departure).FirstOrDefault()
}
);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜