Linq查询在空时不返回null

Nic*_*ick 2 .net c# linq asp.net-core

我正在使用.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();
}
Run Code Online (Sandbox Code Playgroud)

sty*_*ybl 8

您当前的方法存在两个问题.一种是您选择的方法,另一种是您尝试在同步上下文中使用它,即使它是异步的.

首先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();
}
Run Code Online (Sandbox Code Playgroud)

同步运行任务如下所示:

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

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

    return View();
}
Run Code Online (Sandbox Code Playgroud)

但是,您可能会遇到另一个问题.根据数据类型SingleOrDefault和其他类似的方法,FirstOrDefault可能永远不会返回null.所有非可空内置类型(如布尔值,整数等)就是这种情况.如果您想要一个适用于所有情况的替代方案,那么try-catch是您最好的选择:

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

如果你不想这样做,那么考虑将事情分开:

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