Linq查询在空时不返回null

时间:2017-09-24 14:11:06

标签: c# .net linq asp.net-core

我正在使用.NetCore 1.1.2。当我为row = int(input("Enter Row : ")) col = int(input("Enter Col : ")) # declare array baru namanya peta peta = [] # array 2 dimensi # Masukkin smua input ke array petas for i in range(0,row): line = input() peta.append(line) store = [] # declare array baru nama visited visited = [] for i in range(0,row): visited.append([]) # buat column di row i false smua for j in range(0,col): visited[i].append(False) def dfs(i,j): visited[i][j] = True a = row-1 b = col-1 #peta[i][j] = store[a][b] for i in range(i,row): for j in range(j,col): if(visited[i][j] == True): return 1 else: if(peta[i][j] == 'x' and visited[i][j] == False ): #top left array if(i == 0 or j == 0): dfs(i+1,j+1) dfs(i+1,j) dfs(i,j+1) #bottom left array elif(i == a and j == 0): dfs(i-1,j) dfs(i-1,j+1) dfs(i,j+1) #top right array elif(i == 0 and j == b): dfs(i,j-1) dfs(i+1,j-1) dfs(i+1,j) #bottom right array elif(i == a and j == b): dfs(i,j-1) dfs(i-1,j-1) dfs(i-1,j) #west array elif(i >= 1 and j == 0): dfs(i-1,j) dfs(i-1,j+1) dfs(i+1,j) dfs(i,j+1) dfs(i+1,j+1) #north array elif(i==0 and j>=1): dfs(i,j-1) dfs(i+1,j-1) dfs(i+1,j) dfs(i,j+1) dfs(i+1,j+1) #east array elif(i>=1 and j==b): dfs(i-1,j) dfs(i-1,j-1) dfs(i,j-1) dfs(i+1,j-1) dfs(i+1,j) #south array elif(i==a and j>=1): dfs(i,j-1) dfs(i-1,j-1) dfs(i-1,j) dfs(i-1,j+1) dfs(i,j+1) #middle array else: dfs(i-1,j-1) dfs(i-1,j) dfs(i-1,j+1) dfs(i,j-1) dfs(i,j+1) dfs(i+1,j-1) dfs(i+1,j) dfs(i+1,j+1) else: #peta[i][j] = 0 return 0 numberofisland = 0 for i in range(0,row): for j in range(0,col): if((peta[i][j] == 'x' and visited[i][j] == False)): dfs(i,j) numberofisland+=1 print(numberofisland) 操作使用生成的操作时,如果在DB上没有找到任何内容,它应返回null,但Null验证不起作用。

我尝试使用GET代替Single()并使用try catch来抛出异常,但它似乎不是一个优雅的解决方案。

也许是.net版本?

SingleOrDefault

4 个答案:

答案 0 :(得分: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();
}

同步运行任务如下所示:

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

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

    return View();
}

但是,您可能会遇到另一个问题。根据数据类型,SingleOrDefaultFirstOrDefault等其他此类方法可能从不返回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();
}

答案 1 :(得分:0)

如果您不想要列表,请尝试使用FirstOrDefault而不是SingleOrDefault,并依赖于对象paymentMade的数据类型。

如果您需要列表,请使用.Where(m =&gt; m.StripeToken == token).ToList(),并在if if verify paymentMade.Count == 0。

看看这个LINQ: When to use SingleOrDefault vs. FirstOrDefault() with filtering criteria

答案 2 :(得分:0)

您正在使用android.support.design.widget.TabLayout ... android:elevation="6dp" android:margin="10dp" // margin > elevation android:background="@color/white" />asyncSingleOrDefault(),而不是等待&#34;等待&#34;它,你实际拥有的SingleOrDefaultAsync()变量是一个等待的对象,无论如何都不会为空。

有几种方法可以解决这个问题:

1-您执行操作paymentMade并使用async,如下所示:

await

2-您可以调用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(); } 方法的非异步(标准)版本,您的代码将如下所示:

SingleOrDefault()

使用最适合你的那个

答案 3 :(得分: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();
}