【发布时间】:2016-03-07 21:33:00
【问题描述】:
我一直在试验 LinqPad 中的查询。我们有一个表Lot,其中有一列Side char(1)。当我编写一个 linq to 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
但是,使用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
在检查时会出现(尽管很幼稚),后者会稍微快一些,因为它不需要调用UNICODE。
使用int、smallint或varchar列生成的SQL与==或.Equals没有区别,为什么char(1)和对应的C#类型char不同?
有没有办法预测给定的列类型是否会通过两种形式的相等检查产生不同的 SQL?
编辑:
我检查了 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();
}
输出:
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
有趣的是,在== 'A' 版本中,参数作为int 传递,而在.Equals 版本中,它作为char 传递。
【问题讨论】:
-
你能发布 DBML 映射吗?
-
@usr 这是通过 LINQPad,我不知道如何检索映射。
标签: c# linq-to-sql linqpad