The following is the C# code and generated SQL in a LINQ to SQL query for two cases.
Case 1
using (JulianDataContext dc = new JulianDataContext(this.CurrentConnectionString))
{
#if DEBUG
dc.Log = new DebugTextWriter();
#endif
IEnumerable<UserNewsfeedDeliveryTime> temp = dc.UserNewsfeedDeliveryTimes.Where(u => u.NewsfeedEmailPeriodicity > 0 && DateTime.Today >= u.NextNewsfeedDelivery.Value.Date);
ids = temp.Select(p => p.Id).ToList();
}
SELECT [t0].[Id], [t0].[NewsfeedEmailPeriodicity], [t0].[LastSentNewsfeedEmail], [t0].[NextNewsfeedDelivery]
FROM [dbo].[UserNewsfeedDeliveryTimes] AS [t0]
WHERE ([t0].[NewsfeedEmailPeriodicity] > @p0) AND (@p1 >= CONVERT(DATE, [t0].[NextNewsfeedDelivery]))
-- @p0: Input Int (Size = -1; Prec = 0; Scale = 0) [0]
-- @p1: Input DateTime (Size = -1; Prec = 0; Scale = 0) [15-11-2012 00:00:00]
Case 2
using (JulianDataContext dc = new JulianDataContext(this.CurrentConnectionString))
{
#if DEBUG
dc.Log = new DebugTextWriter();
#endif
IEnumerable<UserNewsfeedDeliveryTime> temp = dc.GetTable<UserNewsfeedDeliveryTime>();
temp = temp.Where(u => u.NewsfeedEmailPeriodicity > 0 && DateTime.Today >= u.NextNewsfeedDelivery.Value.Date);
ids = temp.Select(p => p.Id).ToList();
}
SELECT [t0].[Id], [t0].[NewsfeedEmailPeriodicity], [t0].[LastSentNewsfeedEmail], [t0].[NextNewsfeedDelivery]
FROM [dbo].[UserNewsfeedDeliveryTimes] AS [t0]
The difference
The difference between these two linq queries:
dc.UserNewsfeedDeliveryTimes
and
dc.GetTable<UserNewsfeedDeliveryTime>()
Why? Could it be that, in case 2, LINQ to SQL is retrieving all data from database and finish the query by filtering all objects in memory?
If so, how can we make keep this generic and still force all the T-SQL to be generated?
Solution
Both answers, are correct but I had to pick one, sorry! I think also it is interesting to add that in this case, since I changed to work with an IQueryable (inherits from IEnumerable), in this line:
temp = temp.Where(u => u.NewsfeedEmailPeriodicity > 0 && DateTime.Today >= u.NextNewsfeedDelivery.Value.Date);
I had two overload methods, one from the IQueryable interface and another to the IEnumerable interface.
public static IQueryable<TSource> Where<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate);
public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate);
So I had to convert my predicate explicitly to Expression> predicate, otherwise the IEnumerable interface method would have been picked up at compile time and, if I am not mistaken, I would get some dynamic sql exception saying the T-SQL could not have been generated.