通过附加处理,我的意思是除了标准 LINQ 到 SQL 到 Transact SQL 的转换(以及可能的解决方法)
我有两个问题,我希望对这些问题有所了解和/或一些适当的链接或谷歌术语用于查找更多信息,因为我没有找到任何东西。归结为这样一个事实,即我想知道将要执行的 IQueryable 表达式何时/如何确定某些表达式结果需要在“客户端”运行,这意味着无法直接翻译 LINQ 表达式到 Transact SQL 返回整个结果。
这是关于我的帖子/代码。
情况一
string.Format()
不转换为 Transact SQL。我可以接受,但我想我只是在寻找一些关于如何检测表达式是否能够完全转换为 Transact SQL 的建议。
LINQ 表达式:
from h in HistoryData
select new { NewData = string.Format( "New Data: {0}", h.hisData ) };
提供者上下文 SQL:
SELECT [t0].[hisData] AS [arg0]
FROM [HistoryData] AS [t0]
我的解决方法:目前,我正在使用DataContext.GetCommand()
方法,然后查看 Transact SQL 并搜索[arg0]
. 显然不理想,所以我一直在寻找一种更强大的机制(可能用 ExpressionTree 访问者发现一些东西??)
情况2
在某些情况下使用三级运算符似乎会返回一些 Transact SQL,这些 SQL 显然应用了一些后/客户端处理以获取正确的值。在下面的示例中,我在 LINQPad 的上下文中运行(因此Dump()
扩展方法可用)。当三级算子在起作用时,似乎有两种情况需要后处理:
- 当使用布尔变量和布尔字段时(下面的 var testBool... 表达式)和
- 当使用两个变量,无论类型如何,并且没有查询数据库字段(下面的第二个 testNumber 表达式)。
这种情况让我感到惊讶,需要客户端处理。因此,除了学习如何正确检测表达式何时需要在正常 Transact SQL 之外进行额外处理之外,如果有人知道为什么 L2S 不能像其他情况一样执行简单的 CASE 语句,更重要的是可能的解决方法可用于避免任何很棒的“客户端”处理!
LINQ 表达式:
var before9_1_2009 = DateTime.Today < new DateTime( 2009, 9, 1 );
var fiveThousand = 5000;
var tenThousand = 10000;
var testNumber =
Profiles.Where( p => p.pAuthID == "111111111" )
.Select( p => new { Number = before9_1_2009 ? fiveThousand : p.pKey } );
var cmd = GetCommand( testNumber );
cmd.CommandText.Dump( "Number Property: Works (i.e. evaluates on SQL Server)" );
var testString =
Profiles.Where( p => p.pAuthID == "111111111" )
.Select( p => new { String = before9_1_2009 ? "StringConstant" : p.pAuthID } );
cmd = GetCommand( testString );
cmd.CommandText.Dump( "String Property: Works (i.e. evaluates on SQL Server)" );
var testBool =
Profiles.Where( p => p.pAuthID == "111111111" )
.Select( p => new { Boolean = boolExp ? true : p.pProcessed } );
cmd = GetCommand( testBool );
cmd.CommandText.Dump( "Boolean Property: Has NULL AS [EMPTY] - Post Processing Needed" );
testNumber =
Profiles.Where( p => p.pAuthID == "111111111" )
.Select( p => new { Number = before9_1_2009 ? fiveThousand : tenThousand } );
cmd = GetCommand( testNumber );
cmd.CommandText.Dump( "Number Property (using two constants): Has NULL AS [EMPTY] - Post Processing Needed" );
提供者上下文 SQL(按顺序): ▪ Number 属性:有效(即在 SQL Server 上评估)
SELECT
(CASE
WHEN @p1 = 1 THEN @p2
ELSE [t0].[pKey]
END) AS [Number]
FROM [Profile] AS [t0]
WHERE [t0].[pAuthID] = @p0
▪ 字符串属性:有效(即在 SQL Server 上评估)
SELECT
(CASE
WHEN @p1 = 1 THEN CONVERT(NVarChar(255),@p2)
ELSE [t0].[pAuthID]
END) AS [String]
FROM [Profile] AS [t0]
WHERE [t0].[pAuthID] = @p0
▪ 布尔属性:具有 NULL AS [EMPTY]
SELECT NULL AS [EMPTY]
FROM [Profile] AS [t0]
WHERE [t0].[pAuthID] = @p0
▪ Number 属性(使用两个常量):Has NULL AS [EMPTY]
SELECT NULL AS [EMPTY]
FROM [Profile] AS [t0]
WHERE [t0].[pAuthID] = @p0
我的解决方法:我再次使用DataContext.GetCommand()
方法,然后查看 Transact SQL 并搜索NULL AS [EMPTY]
. 想知道对于无法在服务器上运行的表达式代码是否还会出现任何其他“魔术字符串”……所以如上所述,我正在寻找一种正确、更可靠的方法来检测这些情况。