Roa*_*ich 21 c# linqpad linq-to-sql
我一直在试验LinqPad中的查询.我们有一个Lot带有列的表Side char(1).当我将linq写入sql查询时Lots.Where(l => l.Side == 'A'),它会生成以下SQL
-- Region Parameters
DECLARE @p0 Int = 65
-- EndRegion
SELECT ..., [t0].[Side], ...
FROM [Lot] AS [t0]
WHERE UNICODE([t0].[Side]) = @p0
Run Code Online (Sandbox Code Playgroud)
然而,使用Lots.Where(l => l.Side.Equals('A')),它产生
-- Region Parameters
DECLARE @p0 Char(1) = 'A'
-- EndRegion
SELECT ..., [t0].[Side], ...
FROM [Lot] AS [t0]
WHERE [t0].[Side] = @p0
Run Code Online (Sandbox Code Playgroud)
它会出现(尽管是天真的)检查,后者会略微加快,因为它不需要调用UNICODE.
使用int,smallint或varchar列有与所生产的SQL没有区别==或者.Equals,为什么char(1)和相应的C#类型char不同?
有没有办法预测给定的列类型是否会产生两种形式的相等性检查?
编辑:
我已经检查通过MS SQL支持所有类型的,只有char(1)和nchar(1)显示此行为.两者都在LinqToSql中以System.Char类型表示.如果这是一个刻意的决定,那么我会期望相同的行为binary(1),可以表示System.Byte(但相反System.Linq.Binary,长度为1.
编辑2:如果它是相关的,我使用LINQPad来查看创建的SQL.我假设Linqpad会使用系统的LinqToSQL,但我今天意识到这个假设可能存在缺陷.
编辑3:我运行了一个快速VS项目来测试系统LinqToSQL,我们得到了相同的结果:
码:
static void Main(string[] args)
{
var db = new DataClasses1DataContext {Log = Console.Out};
Console.Out.WriteLine("l.Side == 'A'");
Console.Out.WriteLine("=============");
Console.Out.WriteLine();
foreach (Lot ll in db.Lots.Where(l => l.Side == 'A'))
{
break;
}
Console.Out.WriteLine();
Console.Out.WriteLine("---------------------------------------");
Console.Out.WriteLine();
Console.Out.WriteLine("l.Side.Equals('A')");
Console.Out.WriteLine("==================");
Console.Out.WriteLine();
foreach (Lot ll in db.Lots.Where(l => l.Side.Equals('A')))
{
break;
}
Console.In.Read();
}
Run Code Online (Sandbox Code Playgroud)
输出:
l.Side == 'A'
=============
SELECT ..., [t0].[Side], ...
FROM [dbo].[Lot] AS [t0]
WHERE UNICODE([t0].[Side]) = @p0
-- @p0: Input Int (Size = -1; Prec = 0; Scale = 0) [65]
-- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 4.6.1532.0
---------------------------------------
l.Side.Equals('A')
==================
SELECT ..., [t0].[Side], ...
FROM [dbo].[Lot] AS [t0]
WHERE [t0].[Side] = @p0
-- @p0: Input Char (Size = 1; Prec = 0; Scale = 0) [A]
-- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 4.6.1532.0
Run Code Online (Sandbox Code Playgroud)
有趣的是,在== 'A'版本中,参数作为一个传递int,而在.Equals版本中,它作为传递char.
usr*_*usr 12
有一些关于此的文档:
SQL Server中的不匹配:固定长度的字符类型.Transact-SQL区分Unicode和非Unicode类别,并且在每个类别中有三种不同的类型:固定长度nchar/char,可变长度nvarchar/varchar和更大的ntext/text.固定长度字符类型可以映射到CLR System.Char类型以检索字符,但它们实际上并不对应于转换和行为中的相同类型.
L2S源代码只有一个使用字符串文字的地方"UNICODE":
似乎函数显示的必要前提条件是SqlUnary语法树节点,其类型为Convert:
我不知道你是如何设法满足这个IsNumeric条件的.我认为你的类型不匹配.该列是否真的映射为System.Char?
该Equals呼叫可能不会触发此代码路径.这可能是一个L2S错误.
Equals在源代码中的多个位置被翻译.这是其中之一:
看起来这会绕过任何参数转换.它并不关心论证是什么.这可能会因各种查询而失败(因此可能存在错误).我想知道如果你写的会发生什么l.Side.Equals(1.2m).我想这可以转化为SQL.
我现在转载它.将列映射到string.这可以修复生成的SQL.执行计划显示可以使用正在生成的SQL进行索引搜索.
| 归档时间: |
|
| 查看次数: |
352 次 |
| 最近记录: |