以下は、2つのケースのLINQ to SQLクエリで生成されたC#コードとSQLです。
ケース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]
ケース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]
違い
これら2つのlinqクエリの違い:
dc.UserNewsfeedDeliveryTimes
と
dc.GetTable <UserNewsfeedDeliveryTime>()
なんで?ケース2の場合、LINQ to SQLがデータベースからすべてのデータを取得し、メモリ内のすべてのオブジェクトをフィルタリングしてクエリを終了している可能性がありますか?
もしそうなら、どうすればこれを汎用的に保ちながら、すべてのT-SQLを強制的に生成させることができますか?
解決
どちらの答えも正解ですが、どちらかを選択する必要がありました。ごめんなさい。この場合、IQueryable(IEnumerableから継承)を使用するように変更したので、次の行にこれを追加することも興味深いと思います。
temp = temp.Where(u => u.NewsfeedEmailPeriodicity> 0 && DateTime.Today> = u.NextNewsfeedDelivery.Value.Date);
2つのオーバーロードメソッドがありました。1つはIQueryableインターフェイスから、もう1つはIEnumerableインターフェイスからです。
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);
そのため、述語を明示的にExpression> predicateに変換する必要がありました。そうしないと、コンパイル時にIEnumerableインターフェイスメソッドが取得され、間違えなければ、T-SQLでは不可能であるという動的SQL例外が発生します。生成されます。