Eksperymentowałem z zapytaniami w LinqPad. stół Lot
z kolumną Side char(1)
. Kiedy piszę LINQ do zapytania sql Lots.Where(l => l.Side == 'A')
, produkuje następujące SQLRóżne SQL utworzone z Where (l => l.Side == "A") vs Where (l => l.Side.Equals ("A")
-- Region Parameters
DECLARE @p0 Int = 65
-- EndRegion
SELECT ..., [t0].[Side], ...
FROM [Lot] AS [t0]
WHERE UNICODE([t0].[Side]) = @p0
jednak użycie Lots.Where(l => l.Side.Equals('A'))
, produkuje
-- Region Parameters
DECLARE @p0 Char(1) = 'A'
-- EndRegion
SELECT ..., [t0].[Side], ...
FROM [Lot] AS [t0]
WHERE [t0].[Side] = @p0
wydaje się na (choć naiwny) inspekcję, że ta ostatnia byłaby marginalnie szybsza, jak to robią musisz zadzwonić pod numer UNICODE
.
Korzystanie int
, smallint
lub varchar
kolumn nie ma różnicy pomiędzy produkowanego SQL z ==
lub .Equals
, dlaczego char(1)
i odpowiedni typ C# char
inaczej?
Czy istnieje sposób przewidzieć, czy dany typ kolumny będzie produkować różne SQL z dwóch form kontroli równości?
Edit:
Sprawdziłem każdy rodzaj obsługiwanego przez MS SQL, a jedynie char(1)
i nchar(1)
pokazują to zachowanie. Oba są reprezentowane w LinqToSql przez typ System.Char
. Jeśli to była przemyślana decyzja, to bym oczekiwał, że samo zachowanie na binary(1)
, które mogą być reprezentowane przez System.Byte
(lecz jest System.Linq.Binary
o długości 1
Edit. 2: W przypadku istotne jest, jestem Używając LINQPada do wyświetlenia utworzonego SQL, zakładałem, że Linqpad użyje LinqToSQL w systemie, ale zdałem sobie sprawę, że to założenie może być błędne
Edycja 3: Uruchomiłem szybki projekt VS, aby przetestować system LinqToSQL, a my uzyskać ten sam wynik:
Kod:
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();
}
wyjściowa:
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
Warto zwrócić uwagę, że w wersji == 'A'
parametr jest przekazywana jako int
, natomiast w wersji .Equals
, jest przekazywana jako char
.
The dbml and table creation script are in this gist.
Czy możesz opublikować mapowanie DBML? – usr
@usr to było przez LINQPad, dla którego nie wiem jak odzyskać mapowanie. – RoadieRich