EF Core中的&和&&有什么区别

时间:2019-02-20 08:19:42

标签: entity-framework entity-framework-core ef-core-2.2

我了解到&&会缩短评估的速度,因此不必评估RHS,但是EF呢? &和&&之间有什么区别(与|和||相同)?性能方面!

3 个答案:

答案 0 :(得分:4)

  

但是EF呢? &和&&之间有什么区别(与|和||相同)?性能方面!

是的,有。

首先,有时EF Core使用client evaluation,因此不能使其短路。

第二,即使使用服务器评估,EF Core也会对其进行不同的转换。例如,这是SqlServer的翻译:

LINQ             SQL
==============   ============ 
expr1 && expr2   expr1 AND expr2
expr1 & expr2    (expr1 & expr2) = 1

这是否影响性能取决于数据库查询优化器,但通常看起来更好。并且某些不提供对bool类型的本机支持的数据库提供程序可能会产生效率低下的转换,甚至无法转换& / |谓词。

不久,最好在LINQ查询中始终使用逻辑&&||运算符。

答案 1 :(得分:2)

根据Microsoft文档:

1。& Operator有两种形式的支持:一元地址运算符二进制逻辑运算符。

运营商的统一地址:

一元&运算符返回其操作数的地址。有关更多信息,请参见How to: obtain the address of a variable。地址运算符&需要不安全的上下文。

整数逻辑按位AND运算符:

对于整数类型,&运算符计算其操作数的逻辑按位AND

uint a = 0b_1111_1000;
uint b = 0b_1001_1111;
uint c = a & b;
Console.WriteLine(Convert.ToString(c, toBase: 2));
// Output:
// 10011000

2。&& Operator是条件逻辑AND运算符,也称为“短路”逻辑AND运算符,用于计算其布尔操作数的逻辑AND。如果x && yx都等于y,则true的结果为true。否则,结果为false。如果第一个操作数的求值为false,则不计算第二个操作数,并且运算的结果为false。下面的示例演示该行为:

bool SecondOperand()
{
    Console.WriteLine("Second operand is evaluated.");
    return true;
}

bool a = false && SecondOperand(); // <-- second operand is not evaluated here
Console.WriteLine(a);
// Output:
// False

bool b = true && SecondOperand(); // <-- second operand is evaluated here
Console.WriteLine(b);
// Output:
// Second operand is evaluated.
// True

现在,在EF / EF核心行为的情况下,@ Ivan Stoev进行了重大解释: Here

答案 2 :(得分:1)

我决定做一个实验:

var t1 = _db.Customers
.Where(x => x.FirstName == "james" | x.FirstName == "thomas")
.Select(x=>x.CustomerId).ToList();

vs。

var t2 = _db.Customers
.Where(x => x.FirstName == "james" || x.FirstName == "thomas")
.Select(x => x.CustomerId).ToList();

t1执行为:

SELECT [x].[CustomerId]
FROM [Customers] AS [x]
WHERE (CASE
    WHEN [x].[FirstName] = N'james'
    THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT)
END | CASE
    WHEN [x].[FirstName] = N'thomas'
    THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT)
END) = 1

和t2为:

SELECT [x].[CustomerId]
FROM [Customers] AS [x]
WHERE [x].[FirstName] IN (N'james', N'thomas')

两者返回相同的结果。我比较了他们的执行计划,执行t1我有“索引扫描”,而执行t2我有“索引搜索”。正如贾斯汀(SQL Server Plans : difference between Index Scan / Index Seek)所言:“查找总是比扫描更好,因为查找数据的效率更高。”

因此,使用|或&不仅会导致客户端评估,还会影响生成的sql。

谢谢大家!