簡體   English   中英

Linq查詢在空時不返回null

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

看看這個LINQ:何時使用SingleOrDefault與FirstOrDefault()一起使用過濾條件

您正在使用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.

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