[英]LINQ to SQL with null values
任何人都可以幫我解決這個問題嗎?
下面的代碼工作正常,並進入if statument
foreach (var m in msg)
{
if (string.IsNullOrEmpty(m.PhoneNumber))
{
m.PhoneNumber = (from c in db.Customers
where c.CustomerID == m.CustomerID
select c.PhoneNumber).Single();
}
}
但是在下面的代碼中,phoneNumber從未設置
foreach (var m in msg.Where(z => (z.PhoneNumber == null || z.PhoneNumber == "")))
{
m.PhoneNumber = (from c in db.Customers
where c.CustomerID == m.CustomerID
select c.PhoneNumber).Single();
}
我推測它是因為頂級代碼實際上評估了表達式,而下面的劑量。 如果是這種情況,那么如何在未評估的LINQ查詢中檢查null?
編輯只是為了在這里停止混淆是如何在兩種情況下彈出消息
var msg = from m in db.Messages
where (m.StatusID == (int)MessageStatus.Submitted && m.MessageBoxTypeID == (int)MessageBoxType.Outbox)
select m;
我對這個感到有些困惑,但我有一個瘋狂的猜測。 如果msg
序列是IQueryable<T>
,它轉換為SQL查詢,則兩個片段的行為可能會有所不同。 假設你有:
var msg =
from m in dataContext.MyTable
select m;
您的第一個片段將導致整個msg
序列被枚舉,從而向數據庫發出未過濾的SELECT…FROM
命令並獲取表中的所有行。
foreach (var m in msg)
另一方面,您的第二個代碼段在枚舉之前會對您的序列應用過濾器。 因此,發出給數據庫的命令是SELECT…FROM…WHERE
。
foreach (var m in msg.Where(z => (z.PhoneNumber == null || z.PhoneNumber == "")))
在各種情況下,.NET中應用的過濾器的行為與其對Transact-SQL的轉換有所不同。 例如,區分大小寫。 在您的情況下,我假設不匹配是由PhoneNumber
由空格組成的條目引起的,因為這些條目可能與SQL Server中的空字符串匹配。
要測試這種可能性,請檢查如果將第二個代碼段更改為:
foreach (var m in msg.ToList().Where(z => (z.PhoneNumber == null || z.PhoneNumber == "")))
編輯 :您的問題可能是您在后續訪問期間再次執行查詢(當您檢查是否已設置PhoneNumber
時)。
如果你執行:
foreach (var m in msg.Where(z => (z.PhoneNumber == null || z.PhoneNumber == "")))
{
m.PhoneNumber = …
}
bool stillHasNulls = msg.Any(z => z.PhoneNumber == null || z.PhoneNumber == "");
你會發現stillHasNulls
仍然可以評估為true
,因為當你重新評估msg
序列時你的m.PhoneNumber
賦值會丟失(在上面的例子中,當你執行msg.Any
,會向數據庫發出一個EXISTS
命令) )。
要保留m.PhoneNumber
分配,您需要將它們保存到數據庫(如果這是您想要的),或者確保每次都訪問相同的序列元素。 一種方法是使用ToList
將序列預先填充為集合。
msg = msg.Where(z => (z.PhoneNumber == null || z.PhoneNumber == "")).ToList();
foreach (var m in msg)
{
m.PhoneNumber = …
}
在上面的代碼中,過濾器仍然作為SELECT…FROM…WHERE
發布到數據庫,但是結果被急切地評估,然后作為列表存儲在msg
。 msg
上的任何后續查詢都將根據預先填充的內存中集合(包含您為其元素指定的任何新值)進行評估。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.