簡體   English   中英

LINQ to SQL具有空值

[英]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.

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