Reputation: 1343
I have the following 2 tables in my database:
[Schedule](
[Time] [datetime] NULL,
[ScheduleID] [bigint] IDENTITY(1,1) NOT NULL,
[PatientID] [varchar](20) NULL,
CONSTRAINT [PK_Schedule] PRIMARY KEY CLUSTERED
(
[ScheduleID] ASC
)
and:
[Patient](
[NameLast] [varchar](20) NOT NULL,
[NameMiddle] [varchar](20) NULL,
[NameFirst] [varchar](20) NOT NULL,
[DOB] [varchar](20) NULL,
[PatientID] [varchar](20) NOT NULL,
CONSTRAINT [PK_Patient] PRIMARY KEY CLUSTERED
(
[PatientID] ASC
)
And I want to accomplish the following SQL, except using linq methods with Entity Framework:
select NameFirst, NameLast, DOB
from Patient
join Schedule on Schedule.PatientID = Patient.PatientID
where Schedule.Time < GETDATE()
I know how to create a join, using my mappings, so creating a join isn't the problem. I also know how to do the date functionality I need so that isn't the problem.
I need to know how to accomplish (using linq methods) the part that says: where Schedule.Time < SOMETHING
Here's what I have tried, but it threw an error:
var patients = context.Patient
.Include(x =>
x.Schedule.Where(y => y.Time < DateTime.Now)
);
The error it gave me was: "The Include path expression must refer to a navigation property defined on the type."
So, how can I accomplish a "Where" on a joined table, like I can in SQL, using linq methods with Entity Framework?
I can't do context.Patients.Where(x => x.Schedules.Time == DateTime.Now);
because Patient.Schedules
is a collection, since this is a one-to-many relationship.
Upvotes: 0
Views: 45
Reputation: 30454
First, I'm not sure if it is wise to do the GetDate() inside your query, as an IQueryable
I think it wouldn't work, and as an IEnumerable
I'm not sure how many times it would be called during the enumeration.
You could first filter the Schedules you want to use and then do the join.
In small steps:
DateTime myDate = GetDate();
var oldSchedules = dbCntext.Schedules.Where(schedule => schedule.Time < myDate);
var requiredResult = dbContext.Patients // join Patients
.join(oldSchedules, // with the old schedules
patient => patient.PatientID, // from patients take PatientID
schedule => schedule.PatientID< // from old schedules that PatientID
(patient, schedule) => new // when they match, take the recods
{ // to create a new Anonymous type
NameFirst = patient.NameFirst, // with the required properties
NameLast = patient.NameLast,
Dob = patient.Dob,
});
Of course you could put this in one statement (except for GetDate())
DateTime myDate = GetDate();
var result = dbContext.Schedules
.Where(schedule => schedule.Time < myDate)
.Join(dbContext.Patients,
schedule => schedule.PatientId,
patient => patient.PatientId,
(schedule, patient) => new
{
...
});
Upvotes: 0
Reputation: 89006
Something like
context.Schedule.Where(y => y.Time < DateTime.Now).Select( s => s.Patient);
or
context.Patient.Where( p => p.Schedules.Any( s => s.Time < DateTime.Now) );
Upvotes: 2
Reputation: 4907
from t1 in db.Patient
join t2 in db.Schedule on
t1.PatientId equals t2.PatientId
where t2.Time<getTime
select new { t1.NameFirst, t1.NameLast, t1.DOB}
Upvotes: 1