Yes, LINQ can be inefficient, particularly if it's inside a loop as it is here.
Should I define a local IQueryable equal to the LINQ query result and then read data from that object?
That's probably a good idea.
The wkendQuery query doesn't change inside the loop. But when you execute its ToArray method (inside the loop), it executes the query and moves the result into an array each time. You might think it would be smart enough to keep the array around, but it's not and rebuilds it each time.
So you can probably get a big improvement if you just move the ToArray call outside of the loop. Something like this:
wkendQuery = From wkendSchedule As MilestoneWeekendSchedule
MilestoneWeekendSchedule weekends = wkendQuery.ToArray()
For j = 0 To dgvWaterfall.Columns.Count - 1
If wkendQuery.ToArray.Length >= 0 Then
For Each wkend In weekends
If wkend.weekendDate = dgvWaterfall.Columns(j).HeaderText Then
If that isn't a big enough improvement, then you'll need to look at other ways to store the milestone weekend schedules from which you're pulling data. For example, if you store the data in a sorted list or database with an index on the milestoneStatusID field, you may be able to find the data you need more quickly than the sequential search that LINQ is probably performing.
(My guess is you'll see a big improvement just by moving the call to ToArray.)