我在sql server数据库中有一个表,其中year
列的类型为shortint
,qtr
列的类型为tinyint
。使用实体框架导入此表时,相应属性的类型为short
和byte
。现在,当我尝试运行这样的查询时:
query = myTable.Where(a => a.year > qyear || (a.year == year && a.qtr >= qqtr));
qyear
和qqtr
又分别是short
和byte
,如果我查看生成的SQL(使用myContext.Database.Log = s => System.Diagnostics.Debug.Writeline(s);
),我会看到:< / p>
SELECT
[Extent1].[year] as [year],
[Extent1].[qtr] as [qtr],
/* a bunch of other fields */
FROM [dbo].[myTable] as [Extent1]
WHERE (( CAST( [Extent1].[year] AS int) > @p__linq__0) OR
(((( CAST( [Extent1].[year] AS int) = @p__linq__1) AND
( NOT (( CAST( [Extent1].[year] AS int) IS NULL) OR
(@p__linq__1 IS NULL)))) OR (( CAST( [Extent1].[year] AS int) IS NULL)
AND (@p__linq__1 IS NULL))) AND ( CAST( [Extent1].[qtr] AS int) >= @p__linq__2)))
为什么所有内容都会被转换为int
进行比较?
答案 0 :(得分:2)
为什么所有内容都会被转换为int进行比较?
因为这是C#语言定义的内容。它没有在byte
,short
等上定义任何运算符 - 在发生任何事情之前,它们都会被提升为int
。这也会传播到表达式树。举个例子:
using System;
using System.Linq.Expressions;
public class Test
{
public static void Main()
{
Expression<Func<byte, byte, bool>> func = (x, y) => x > y;
Console.WriteLine(func);
}
}
打印
(x, y) => (Convert(x) > Convert(y))
如果您查看IL,您会看到Convert
来电有效
Convert(xParameterExpression, typeof(int))
和
Convert(yParameterExpression, typeof(int))
因此,SQL正在代表完全你的C#所代表的......我希望它的行为也完全相同。如果这有任何成本,我会感到惊讶 - 任何体面的查询优化器都会意识到它可以只使用这些值,而不是真正依次转换每个值。