2017-09-24 75 views
2

我正在使用.NetCore 1.1.2。當我爲GET操作使用生成的操作時,如果在數據庫上找不到任何內容,它應該返回null,但空值驗證不起作用。Linq查詢在空時不返回空值

我嘗試使用Single()而不是SingleOrDefault並使用try catch來拋出異常,但它似乎不是一個優雅的解決方案。

也許這是.net版本?

public IActionResult Success(string token) 
{ 
    var paymentMade = _context.Payments 
      .SingleOrDefaultAsync(m => m.StripeToken == token); 

    if (paymentMade == null) 
    { 
     return NotFound(); //this never gets fired when empty 
    } 

    return View(); 
} 
+0

我想你是在FirstOrDefault之後? – user12345

+0

您是如何定義付款的? –

+0

嘿,不要使用'Async' - 檢查'paymentMate'變量的類型。使用同步版本或「await」。 –

回答

7

您目前的方法有兩個問題。一種是您選擇的方法,另一種是您嘗試在同步上下文中使用它,即使它是異步的。

首先,SingleOrDefaultAsync與其他異步方法一樣,不返回任何有用的值,而是Task,它是表示異步操作的對象。要獲得上述操作的結果,您必須使用await

爲了做到這一點,您應該讓您的方法異步或同步運行的任務(不推薦,因爲它會阻止線程,直到它完成)。或者,您也可以簡單地使用方法的同步版本SingleOrDefault

你修改爲異步方法會是這個樣子:

public async Task<IActionResult> Success(string token) 
{ 
    var paymentMade = await _context.Payments.SingleOrDefaultAsync(m => m.StripeToken == token); 

    if (paymentMade == null) 
    { 
     return NotFound(); 
    } 

    return View(); 
} 

運行任務同步是這樣的:

public IActionResult Success(string token) 
{ 
    var paymentMade = _context.Payments.SingleOrDefaultAsync(m => m.StripeToken == token).Result; 

    if (paymentMade == null) 
    { 
     return NotFound(); 
    } 

    return View(); 
} 

但是,你可能會遇到的另一個問題。根據數據類型,SingleOrDefault和其他此類方法如FirstOrDefault可能從不返回null。這是所有非空的內置類型,如布爾,整數等,如果你想對所有情況都適用的替代,在try-catch是你最好的選擇的情況下:

try 
{ 
    var paymentMade = _context.Payments.First(m => m.StripeToken == token); 
} 
catch (InvalidOperationException) 
{ 
    return NotFound(); 
} 

如果你不想這樣做,那麼考慮分拆東西像這樣:

var temp = _context.Payments.Where(m => m.StripeToken == token); 
if (!temp.Count == 0) 
{ 
    return NotFound(); 
} 
0

您使用的是async版本的SingleOrDefault()SingleOrDefaultAsync(),而不是「等待」,所以你其實有你paymentMade變量是一個awaitable對象,它不會被空不管。

有幾種方法去做:

1 - 你讓你的行動async和使用await,像這樣:

public async IActionResult Success(string token) 
{ 
    var paymentMade = await _context.Payments 
     .SingleOrDefaultAsync(m => m.StripeToken == token); 

    if (paymentMade == null) 
    { 
     return NotFound(); //this never gets fired when empty 
    } 

    return View(); 
} 

2 - 你叫非異步(標準)版該SingleOrDefault()方法和你的代碼會是這樣的:

public IActionResult Success(string token) 
{ 
    var paymentMade = _context.Payments 
     .SingleOrDefault(m => m.StripeToken == token); 

    if (paymentMade == null) 
    { 
     return NotFound(); //this never gets fired when empty 
    } 

    return View(); 
} 

使用更適合你

的一個
+0

你的最後一個例子是一樣的另一種 – pinkfloydx33

+0

@ pinkfloydx33感謝,是我不好,我只是編輯它 – Luiso

+1

你仍然需要刪除等待 – pinkfloydx33

0

這是因爲SingleOrDefaultAsync實際上返回任務。你應該這樣做。

public async Task<IActionResult> Success(string token) 
{ 

    var paymentMade = await _context.Payments 
     .SingleOrDefaultAsync(m => m.StripeToken == token); 

    if (paymentMade == null) 
    { 
     return NotFound(); //this never gets fired when empty 
    } 

    return View(); 
}