Я экспериментировал с запросами в 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)
и соответствующий тип С# char
отличается?
Есть ли способ предсказать, будет ли заданный тип столбца создавать различный SQL с двумя формами проверки равенства?
Edit:
Я проверил каждый тип, поддерживаемый 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
.