gpt4 book ai didi

c# - 这两个 LINQtoSQL 语句有什么区别?

转载 作者:太空狗 更新时间:2023-10-29 23:42:35 26 4
gpt4 key购买 nike

这两个语句在我看来在逻辑上是一样的,但它们会导致生成不同的 SQL:

#1 
var people = _DB.People.Where(p => p.Status == MyPersonEnum.STUDENT.ToString());
var ids = people.Select(p => p.Id);
var cars = _DB.Cars.Where(c => ids.Contains(c.PersonId));

#2
string s = MyPersonEnum.STUDENT.ToString();
var people = _DB.People.Where(p => p.Status == s);
var ids = people.Select(p => p.Id);
var cars = _DB.Cars.Where(c => ids.Contains(c.PersonId));

示例 #1 无效,但示例 #2 有效。

var people 查询生成的 SQL 对两者都是相同的,但最终查询中的 SQL 不同,如下所示:

#1
SELECT [t0].[PersonId], [t0].[etc].....
FROM [Cars] AS [t0]
WHERE EXISTS(
SELECT NULL AS [EMPTY]
FROM [People] AS [t1]
WHERE ([t1].[Id] = [t0].[PersonId]) AND ([t1].[Status] = (CONVERT(NVarChar,@p0)))
)

#2
SELECT [t0].[PersonId], [t0].[etc].....
FROM [Cars] AS [t0]
WHERE EXISTS(
SELECT NULL AS [EMPTY]
FROM [People] AS [t1]
WHERE ([t1].[Id] = [t0].[PersonId]) AND ([t1].[Status] = @p0)
)

为什么会有这种差异?

编辑:

到目前为止,我为生成 SQL 所做的所有工作都是在调试器中检查可查询对象。然而,在按照 Jon 的建议设置了一个记录器之后,似乎执行的 真正 sql 是不同的。

#1 
SELECT [t1].[Id], [t1].etc ... [t0].Id, [t1].etc ...
FROM [Cars] AS [t0], [People] AS [t1]
WHERE ([t1].[Id] = [t0].[PersonId]) AND (EXISTS(
SELECT NULL AS [EMPTY]
FROM [People] AS [t2]
WHERE ([t2].[Id] = [t0].[PersonId]) AND ([t2].[Status] = (CONVERT(NVarChar,@p0)))
)) AND ([t1].[Status] = @p1)
-- @p0: Input Int (Size = 0; Prec = 0; Scale = 0) [2]
-- @p1: Input NVarChar (Size = 7; Prec = 0; Scale = 0) [STUDENT]

#2
SELECT [t1].[Id], [t1].etc ... [t0].Id, [t1].etc ...
FROM [Cars] AS [t0], [People] AS [t1]
WHERE ([t1].[Id] = [t0].[PersonId]) AND (EXISTS(
SELECT NULL AS [EMPTY]
FROM [People] AS [t2]
WHERE ([t2].[Id] = [t0].[PersonId]) AND ([t2].[Status] = @p0)
)) AND ([t1].[Status] = @p1)
-- @p0: Input NVarChar (Size = 7; Prec = 0; Scale = 0) [STUDENT]
-- @p1: Input NVarChar (Size = 7; Prec = 0; Scale = 0) [STUDENT]

最佳答案

首先,考虑一下 e Enum 的双重性质:

enum MyPersonEnum
{
STUDENT, // implicit 1
TEACHER, // implicit 2
DIRECTOR = 10 // explicit 10
}

...

Assert.AreEqual(1, (int)MyPersonEnum.STUDENT);
Assert.AreEqual("STUDENT", MyPersonEnum.STUDENT.ToString());

在第二个示例中,C# 已将 Enum 转换为字符串,因此无需转换,并且假设您的数据库 People.Status 列接受“STUDENT”、“TEACHER”、“DIRECTOR”字符串作为逻辑中的有效值。

区别在于,枚举在 CLR 中的内部表示是整数,而第一个示例,@p 参数作为整数传递,这是 L2S 查询构建器行为,这就是转换的原因。

在我的示例中,如果您的数据库列是一个 int,它接受分配给 Enum 成员 {1,2,10} 的值,那么第一个会起作用。

关于c# - 这两个 LINQtoSQL 语句有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1952137/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com