3 回答

TA貢獻(xiàn)1868條經(jīng)驗 獲得超4個贊
如果您針對 編寫 LINQ 查詢IQueryable
,會發(fā)生什么情況是您在后臺調(diào)用的方法(例如Select
、Where
等)除了記錄您如何調(diào)用它們之外沒有做任何其他事情,即它們記錄謂詞表達(dá)式并繼承一個 LINQ 提供程序。一旦您開始迭代查詢,就會要求提供者執(zhí)行查詢模型。所以基本上,提供者使用表達(dá)式模型為您提供預(yù)期類型的結(jié)果。
提供者絕不需要實際編譯甚至執(zhí)行您作為表達(dá)式交付的代碼(模型)。事實上,LINQ to SQL 或 LINQ to Entities 的全部意義在于提供程序不這樣做,而是將代碼表達(dá)式轉(zhuǎn)換為 SQL。
因此,您的查詢實際上被呈現(xiàn)為 SQL 查詢,并且該查詢的結(jié)果被翻譯回來。因此,您在查詢中看到的變量e
不一定是真正創(chuàng)建的,而只是用于 LINQ 提供程序來編譯 SQL 查詢。但是,大多數(shù)數(shù)據(jù)庫服務(wù)器都有空傳播。
對 LINQ to Objects 運行相同的查詢,您將得到缺少的 NullReferenceException。

TA貢獻(xiàn)1848條經(jīng)驗 獲得超2個贊
您的更新幫助我了解了您真正關(guān)心的問題。關(guān)于 LINQ 查詢,您需要了解的概念是 LINQ 中的延遲執(zhí)行。
請通過以下鏈接了解更多詳情:
現(xiàn)在你的情況會怎樣?您已將查詢存儲在location
變量中。該特定步驟只是初始化部分。它并沒有真正通過您的 ORM 層對您的數(shù)據(jù)庫執(zhí)行查詢。這就是您可以測試的方式。
location
在使用 LINQ 查詢初始化變量的代碼行上放置一個斷點。當(dāng)調(diào)試器在 Visual Studio 中停止時,請轉(zhuǎn)到 SQL Server Management Studio (SSMS) 并啟動 SQL Server Profiler 會話。
現(xiàn)在在 Visual Studio 中按下F10以跳過代碼語句。此時,您將在分析器會話中看到絕對沒有查詢執(zhí)行,如下所示:
這都是因為 LINQ 查詢直到此時才被執(zhí)行。
現(xiàn)在您可以訪問以下代碼行:
foreach (var item in location)
{
var p = item.EquipmentClass.EquipmentType.Name;
}
在您進(jìn)入 foreach 循環(huán)的那一刻,LINQ 查詢被觸發(fā),您將在 SQL Server 探查器中看到相應(yīng)的登錄跟蹤會話。因此,除非枚舉 LINQ 查詢,否則它不會被觸發(fā)。這稱為延遲執(zhí)行,即運行時延遲執(zhí)行直到枚舉。如果您從未location在代碼中枚舉變量,那么查詢執(zhí)行將永遠(yuǎn)不會發(fā)生。
因此,要回答您的查詢,只有在查詢被觸發(fā)時才會出現(xiàn)異常。不是在那之前!
更新 1:您是說 -我沒有得到空引用異常。是的!在您到達(dá)缺少相應(yīng) RHS 加入記錄的記錄之前,您不會得到空引用異常。請查看以下代碼以更好地理解:
class Program
{
static void Main(string[] args)
{
var mylist1 = new List<MyClass1>();
mylist1.Add(new MyClass1 { id = 1, Name1 = "1" });
mylist1.Add(new MyClass1 { id = 2, Name1 = "2" });
var mylist2 = new List<MyClass2>();
mylist2.Add(new MyClass2 { id = 1, Name2 = "1" });
var location = from l in mylist1
join e in mylist2 on l.id equals e.id into rs1
from e in rs1.DefaultIfEmpty()
//where ids.Contains(l.ID)
select new
{
EquipmentClass = e,
InServiceStatus = e == null ? 1 : e.id,
EquipmentType = e.id
};
foreach (var item in location)
{
}
}
}
class MyClass1
{
public int id { get; set; }
public string Name1 { get; set; }
}
class MyClass2
{
public int id { get; set; }
public string Name2 { get; set; }
}
所以,現(xiàn)在當(dāng)我開始迭代location變量時,它不會在第一次迭代中中斷。它在第二次迭代中中斷。當(dāng)它無法獲得與2 中存在的MyClass1對象對應(yīng)的記錄/對象時,它會中斷。2沒有任何對象。希望這會有所幫助!idmylist1mylist2id

TA貢獻(xiàn)1827條經(jīng)驗 獲得超8個贊
你的e.EquipmentType.Name
isnull
并且它被分配給它并且分配給一個類型EquipmentType
是非常好的,你正在使用它,如果它不匹配任何條件,它將使用它們的默認(rèn)值初始化元素,在這種情況下,你被設(shè)置為哪個很好我猜。使用它會拋出異常。null
nullable
DefaultIfEmpty()
e.ElementType.Name
null
ToList()
我希望我說得有道理,你們可能已經(jīng)討論過這個問題。
- 3 回答
- 0 關(guān)注
- 146 瀏覽
添加回答
舉報