2011-04-25 24 views
1

我有一個可空INT視圖模型返回false ...。任何()與Nullables - 當我期待真正

public ObjectViewModel(){ 
    public int? Total 
} 

...而且有我的DB幾行,其中總量null

儘管如此,這總是返回

bool exists = repo.AllRows() // renamed this for clarity; returns IQueryable 
        .Any(r => r.Total == vm.Total); // I know r.Total and vm.Total 
                // are both null 

但下面的回報(預期):

bool exists = repo.All().Any(r => r.Total == null); 

任何想法,我做錯了什麼?

+1

如果vm爲空,您將得到一個NullReferenceException。 – 2011-04-25 21:23:32

+0

從哪裏得到vm,它有什麼價值?從結果中我預計它有一個值不存在於結果集中。 – 2011-04-25 21:26:06

+1

在「Any」之前調用「All」的目的是什麼? – 2011-04-25 21:26:52

回答

3

假設你的意思是「vm.Total爲空」和All()是一個錯字...

我覺得你的問題是這個被翻譯成SQL的方式:

  • 第一查詢被轉換爲使用IS NULL
r.Total = @param1
  • WHERE子句所述第二查詢被轉換爲一個WHERE子句

    MSDN has a good description on NULL

    NULL值表示的值是 未知的。空值或零值與空值 不同。沒有兩個 空值相等。在兩個空值之間或在 NULL與任何其他值之間比較 ,返回 未知,因爲每個NULL 的值都是未知的。

    這意味着你不能在SQL中使用比較運算符 - 因此你也不能在Linq中使用sql。

    一些解決這個方法是:

  • +0

    +1,這肯定是C#和SQL中不匹配的一個例子。我相信你可以在C#中使用null合併運算符(?)來讓LINQ使用ISNULL(foo,0)來代替。至於All()調用,不僅不需要它,而且不會編譯。我懷疑這是一個錯誤。 – Josh 2011-04-25 21:38:10

    +0

    添加鏈接到博客文章 - http://www.brentlamborn.com/post/LINQ-to-SQL-Null-check-in-Where-Clause.aspx – Stuart 2011-04-25 21:40:57

    +0

    .All()混淆起因於我有事實在我的倉庫中的一個All()方法,它返回'從上下文選擇m中的m'的結果。我不是指.All()擴展方法。它編譯得很好。 :-) – 2011-04-25 21:53:55

    0

    由於巴拉 - [R說,如果虛擬機爲空,所以你不能夠訪問到Total財產會和它必須拋出NullReferenceException。

    您的查詢應該是:

    bool exists = repo.Any(r => r.Total == null); 
    

    exists將是真實的,如果有一個記錄至少在Total財產null

    0

    如果集合中的任何項目符合由lambda指定的條件,則Any方法將返回true。因此,repo中沒有任何項目的總數等於vm.Total但是有些項目爲空,因此第二個項目返回true。

    要驗證,泛起一點點調試代碼在那裏,

    Console.WriteLine("vm.Total=" + vm.Total.ToString()); 
    foreach (var r in repo) 
        Console.WriteLine("r.Total=" r.Total == null ? "null" : r.Total.ToString()); 
    

    而且看一看的項目,你不應該看到r.Total等於vm.Total,你會看到至少一個null

    0

    您的代碼應該給出一個例外,但無論哪種方式,你可以嘗試:

    Any(r => r.Total == vm==null ? null : vm.Total) 
    
    +0

    我明白你在說什麼了,但是你不需要在那裏放一些括號嗎? '任何(r => r.Total ==(vm == null)?null:vm.Total)' – 2011-04-25 22:05:38

    +0

    我沒有真正運行代碼,但我相信你不知道。查找三元運算符或條件運算符,因爲C#喜歡調用它。 http://msdn.microsoft.com/en-us/library/ty67wk28(v=VS.100).aspx – 2011-04-25 22:38:56

    2

    Josh的答案似乎是最準確的給我。使用時只需將空合併運算符:

    bool exists = repo.AllRows().Any(r => r.Total ?? 0 == vm.Total ?? 0); 
    

    ...你會不會有一種 「WHERE NULL = NULL」 了,但 「WHERE 0 = 0」,這是好的。