LINQ to SQL数据上下文日志不显示WHERE子句

Fab*_*iro 5 linq sql-server linq-to-objects linq-to-sql

以下是C#代码,并在两种情况下在LINQ to SQL查询中生成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]
Run Code Online (Sandbox Code Playgroud)

案例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]
Run Code Online (Sandbox Code Playgroud)

区别

这两个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);

我有两个重载方法,一个来自IQueryable接口,另一个来自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);
Run Code Online (Sandbox Code Playgroud)

所以我必须将我的谓词显式转换为Expression> predicate,否则IEnumerable接口方法将在编译时被拾取,如果我没有弄错,我会得到一些动态的sql异常,说T-SQL不可能产生.

Mig*_*Mig 2

据我了解,IEnumerable不会转换原始查询所IQueryable保存的信息。这几乎就像强制转换IQueryable在强制转换时冻结了查询的任何更改一样。如果你看一下MSDN,就会发现它IQueryable继承了IEnumerable

http://msdn.microsoft.com/en-us/library/system.linq.iqueryable.aspx

因此,您会看到这种行为。使用 LINQ-SQL 非常重要,IQueryable除非您希望查询在转换IEnumerable.

在您的第一个示例中,where包含原始查询。这select不是因此生成的查询。

在第二个示例中,您将表本身捕获到IEnumerable. 除此之外的任何更改都是在内存中原始查询之上完成的。

当您想到时,由于转换和继承的工作原理,IEnumerable的版本where将无法转换 的原始数据。IQueryable

当您还考虑延迟加载以及 LINQ 的工作原理时,这似乎是有道理的。对我来说,这是一个很大的烦恼,因为它可能会导致您生成一些性能糟糕的代码。