簡體   English   中英

這兩個LINQtoSQL語句之間有什么區別?

[英]What's the difference between these two LINQtoSQL statements?

這兩個語句在邏輯上與我看起來相同,但它們導致生成不同的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)
    )

為什么會出現這種差異?

編輯:

到目前為止,我所做的一切只是為了檢查調試器中的可查詢性。 但是,在設置了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]

不,他們是不同的。 在第一個版本中,表達式MyPersonEnum.STUDENT.ToString()位於表達式樹中 - 它是LINQ to SQL必須轉換為SQL的一部分。 我有興趣看看執行查詢時@p0是什么...

在第二個版本中,您已經評估了表達式,因此LINQ to SQL只會看到對已經是字符串的變量的引用。

我們知道它們的意思相同,但可能是LINQ to SQL沒有足夠的知識來理解它。

出於興趣,他們兩個都有效嗎?

編輯:好的,所以第二個版本的工作原理。 我建議你使用那種形式然后:)在一個理想的世界中,兩者都可以工作 - 但在這種情況下,你似乎需要幫助LINQ to SQL一點。

首先,想想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},則第一個將起作用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM