[英]Linq query NOT returning null when empty
我正在使用.NetCore 1.1.2。 當我為GET
操作使用生成的操作時,它應該在DB上沒有找到任何內容時返回null,但Null驗證不起作用。
我嘗試使用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();
}
您當前的方法存在兩個問題。 一種是您選擇的方法,另一種是您嘗試在同步上下文中使用它,即使它是異步的。
首先,與其他異步方法一樣, 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();
}
如果您不想要列表,請嘗試使用FirstOrDefault而不是SingleOrDefault,並依賴於對象paymentMade的數據類型。
如果你想要一個列表,請使用.Where(m => m.StripeToken == token).ToList(),並在你的if中驗證paymentMade.Count == 0。
您正在使用SingleOrDefault()
的async
版本: SingleOrDefaultAsync()
,並且沒有“等待”它,因此您在paymentMade
變量上實際擁有的是一個等待的對象,無論如何都不會為null。
有幾種方法可以解決它:
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();
}
使用最適合你的那個
這是因為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();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.