3 回答

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

TA貢獻1848條經驗 獲得超2個贊
您的更新幫助我了解了您真正關心的問題。關于 LINQ 查詢,您需要了解的概念是 LINQ 中的延遲執行。
請通過以下鏈接了解更多詳情:
現在你的情況會怎樣?您已將查詢存儲在location
變量中。該特定步驟只是初始化部分。它并沒有真正通過您的 ORM 層對您的數據庫執行查詢。這就是您可以測試的方式。
location
在使用 LINQ 查詢初始化變量的代碼行上放置一個斷點。當調試器在 Visual Studio 中停止時,請轉到 SQL Server Management Studio (SSMS) 并啟動 SQL Server Profiler 會話。
現在在 Visual Studio 中按下F10以跳過代碼語句。此時,您將在分析器會話中看到絕對沒有查詢執行,如下所示:
這都是因為 LINQ 查詢直到此時才被執行。
現在您可以訪問以下代碼行:
foreach (var item in location)
{
var p = item.EquipmentClass.EquipmentType.Name;
}
在您進入 foreach 循環的那一刻,LINQ 查詢被觸發,您將在 SQL Server 探查器中看到相應的登錄跟蹤會話。因此,除非枚舉 LINQ 查詢,否則它不會被觸發。這稱為延遲執行,即運行時延遲執行直到枚舉。如果您從未location在代碼中枚舉變量,那么查詢執行將永遠不會發生。
因此,要回答您的查詢,只有在查詢被觸發時才會出現異常。不是在那之前!
更新 1:您是說 -我沒有得到空引用異常。是的!在您到達缺少相應 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; }
}
所以,現在當我開始迭代location變量時,它不會在第一次迭代中中斷。它在第二次迭代中中斷。當它無法獲得與2 中存在的MyClass1對象對應的記錄/對象時,它會中斷。2沒有任何對象。希望這會有所幫助!idmylist1mylist2id

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