3

SQL 语句正在检索行的 ID。但可能没有这样的行。当我在 GUI 工具中执行特定的 SQL 语句时,它返回“0 行在 0 毫秒内返回:...”。

但是,当我使用 执行相同的 SQL 语句时ExecuteScalarAsync<int>,它返回 0,并且没有发生异常或 null。我怎么知道是否没有这样的行?理论上,可以存在 ID 为 0 的行。

PS:这是我使用 Nuget ( https://github.com/praeclarum/sqlite-net ) 添加的 SQLite-net。它的版本是 1.4.118。SQL 语句非常简单。我更改了字段名称,但基本上是这样的:

using SQLite;

public Task<int> GetLastID()
{
    return RealDatabase.ExecuteScalarAsync<int>
        ("SELECT max(ID) FROM DATA)");
}
4

2 回答 2

1

我用扩展方法解决了这个问题:

using System;
using System.Threading.Tasks;
using SQLite;

namespace MyApp.DB
{
    public class Row<T>
    {
        public T scalar_value { get; set; }
    }

    public class Maybe<T>
    {
        public readonly T Value;
        public Maybe(T v) { Value = v;  }
    }

    public static class SQLiteExtensions
    {
        public async static Task<Maybe<T>> QueryScalarAsync<T>(this SQLite.SQLiteAsyncConnection conn, string sql)
        {
            var res = await conn.QueryAsync<Row<T>>(sql);
            if (res.Count == 0)
            {
                return null;
            }
            else
            {
                return new Maybe<T>(res[0].scalar_value);
            }
        }
    }
}

返回值null表示没有找到任何行,并且任何返回值本身都包装在一个Maybe类中,以便可以区分空值:

var version = await conn_.QueryScalarAsync<int>("SELECT version AS scalar_value FROM schema_version");
if (version == null)
{
    Debug.WriteLine("no rows found");
}
else
{
    Debug.WriteLine(string.Format("value = {0}", version.Value));
}

唯一的问题是您的查询必须包含一个名为scalar_value.

于 2019-03-25T14:57:34.727 回答
0

实际上,提供者没有实现可为空的类型,并且存在一个未解决的问题。

虽然可以切换到不同的提供商(如果您知道轻量级替代方案,请提供建议),但我使用以下 hack。就我而言,我不能简单地避免零 (0) 值,它在数据库中具有特殊含义,我必须将其与无数据区分开来。

public Task<int> GetLastID()
{
    var sRes = RealDatabase.ExecuteScalarAsync<string>
        ("SELECT cast(max(ID) as varchar) FROM DATA)");
    return string.IsNullOrEmpty(sRes) ? null : int.Parse(sRes);

}
于 2018-12-27T19:58:07.493 回答